summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--bucky/app/bucky.js26
-rw-r--r--bucky/app/index.js2
-rw-r--r--bucky/app/router.js26
-rw-r--r--bucky/db/index.js5
-rw-r--r--public/assets/css/bucky.css35
-rw-r--r--public/assets/js/lib/router.js7
-rw-r--r--public/assets/js/lib/views/details/commentform.js7
-rw-r--r--public/assets/js/lib/views/details/index.js2
-rw-r--r--public/assets/js/lib/views/index/lastlog.js2
-rw-r--r--public/assets/js/lib/views/index/threadform.js53
-rw-r--r--public/assets/js/vendor/view/formview.js5
-rw-r--r--views/pages/post.ejs25
-rw-r--r--views/partials/comments.ejs2
-rw-r--r--views/partials/metadata.ejs2
-rw-r--r--views/partials/scripts.ejs1
16 files changed, 187 insertions, 14 deletions
diff --git a/.gitignore b/.gitignore
index e86c1b8..55e95fb 100644
--- a/.gitignore
+++ b/.gitignore
@@ -14,4 +14,5 @@ public/data
search.db
search.db.1
search/db/env/*
+uploads
diff --git a/bucky/app/bucky.js b/bucky/app/bucky.js
index d1aad4d..876a769 100644
--- a/bucky/app/bucky.js
+++ b/bucky/app/bucky.js
@@ -71,6 +71,23 @@ var bucky = module.exports = {
next()
})
},
+ createThread: function (req, res, next){
+ if (! req.body.title || ! req.body.title.length) {
+ res.json({ error: "no title" })
+ return
+ }
+ var data = {
+ thread: res.thread.get('id'),
+ parent_id: req.body.parent_id || -1,
+ username: req.user.get('username'),
+ date: util.now(),
+ comment: req.body.comment,
+ }
+ db.createComment(data).then(function(comment){
+ res.comment = comment
+ next()
+ })
+ },
/* DETAILS */
@@ -125,6 +142,15 @@ var bucky = module.exports = {
next()
})
},
+ ensureKeywords: function (req, res, next){
+ db.getKeywords().then(function(k){
+ if (! k) {
+ return res.sendStatus(404)
+ }
+ res.keywords = k
+ next()
+ })
+ },
ensureThreadsForKeyword: function (req, res, next){
var keyword = req.params.keyword
if (! keyword) {
diff --git a/bucky/app/index.js b/bucky/app/index.js
index 1231914..b88471c 100644
--- a/bucky/app/index.js
+++ b/bucky/app/index.js
@@ -30,7 +30,7 @@ site.init = function(){
app.use(favicon(__dirname + '../../../public/favicon.ico'))
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({ extended: false }))
- app.use( multer({ dest:'./uploads/' }).single("file") )
+ app.use( multer({ dest:'./uploads/' }).multiple("files") )
app.use(session({
key: 'bucky.sid',
diff --git a/bucky/app/router.js b/bucky/app/router.js
index 2fd8d83..c8392da 100644
--- a/bucky/app/router.js
+++ b/bucky/app/router.js
@@ -28,7 +28,20 @@ module.exports = function(app){
app.get("/details/:id", middleware.ensureAuthenticated, function(req, res){
res.render("pages/details", {})
})
-
+
+ app.get("/post/",
+ middleware.ensureAuthenticated,
+ function(req, res){
+ res.render("pages/post", {title: "Start a new thread" })
+ }
+ )
+ app.get("/post/:keyword",
+ middleware.ensureAuthenticated,
+ function(req, res){
+ res.render("pages/post", {title: "Start a new thread" })
+ }
+ )
+
app.post("/api/login", auth.loggedInLocal)
app.get("/api/index",
bucky.ensureLastlog,
@@ -63,8 +76,10 @@ module.exports = function(app){
)
app.post("/api/thread",
middleware.ensureAuthenticated,
+ bucky.createComment,
function(req, res){
// make a new thread
+ res.json(res.thread)
})
app.post("/api/thread/:id/comment",
middleware.ensureAuthenticated,
@@ -108,6 +123,15 @@ module.exports = function(app){
search.success
)
+ app.get("/api/keywords",
+ middleware.ensureAuthenticated,
+ bucky.ensureKeywords,
+ function(req, res){
+ res.json({
+ keywords: res.keywords,
+ })
+ }
+ )
app.get("/api/keyword/:keyword",
middleware.ensureAuthenticated,
bucky.ensureKeyword,
diff --git a/bucky/db/index.js b/bucky/db/index.js
index f7adb7a..3e88fb7 100644
--- a/bucky/db/index.js
+++ b/bucky/db/index.js
@@ -141,7 +141,10 @@ db.removeComment = function(id){
/* KEYWORDS */
db.getKeywords = function (keywords){
- return Keyword.query("where", "keyword", "in", keywords).fetchAll()
+ if (keywords) {
+ return Keyword.query("where", "keyword", "in", keywords).fetchAll()
+ }
+ return Keyword.fetchAll()
}
db.getKeyword = function (keyword) {
return Keyword.query("where", "keyword", "=", keyword).fetch()
diff --git a/public/assets/css/bucky.css b/public/assets/css/bucky.css
index a8901c3..315cad6 100644
--- a/public/assets/css/bucky.css
+++ b/public/assets/css/bucky.css
@@ -8,6 +8,9 @@ body {
font-family: Trebuchet MS, Helvetica, Arial, sans-serif;
padding: 20px 30px;
}
+* {
+ box-sizing: border-box;
+}
small {
font-size: 10px;
}
@@ -86,6 +89,8 @@ table, tr {
.lastlog {
float: right;
+ width: 100%;
+ padding: 5px 0;
}
#sidebar, #content {
@@ -349,6 +354,36 @@ tr:nth-child(even) td.black:hover { background-color: #f8f8f8; color: #000000;
tr:nth-child(even) td.comment { background-color: #f3f1f2; }
tr:nth-child(odd) td.comment { background-color: #fcf8f8; }
+#thread_form form {
+ width: 530px;
+}
+#thread_form input[name=title] {
+ width: 100%;
+ padding: 5px;
+ font-size: 15px;
+ font-family: 'Trebuchet MS', sans-serif;
+ border: 1px solid #888;
+ margin-top: 10px;
+}
+#thread_form textarea {
+ width: 100%;
+ height: 240px;
+ font-family: 'Trebuchet MS', sans-serif;
+ padding: 5px;
+ font-size: 15px;
+ margin: 10px 0;
+}
+#thread_form .inputs {
+ display: flex;
+ flex-direction: row;
+ justify-content: space-between;
+ width: 100%;
+ padding: 5px;
+}
+#thread_form input[type=submit] {
+ margin: 0;
+}
+
#comment_form form {
width: 530px;
margin-top: 5px;
diff --git a/public/assets/js/lib/router.js b/public/assets/js/lib/router.js
index 9879c6c..95b0ac6 100644
--- a/public/assets/js/lib/router.js
+++ b/public/assets/js/lib/router.js
@@ -7,6 +7,8 @@ var SiteRouter = Router.extend({
"/index": 'index',
"/login": 'login',
"/details/:id": 'details',
+ "/post": 'post',
+ "/post/:keyword": 'post',
"/search": 'search',
"/mail": 'mailbox',
"/mail/:mailbox": 'mailbox',
@@ -40,6 +42,11 @@ var SiteRouter = Router.extend({
app.view = new MessageView ()
app.view.load(id)
},
+
+ post: function(keyword){
+ app.view = new ThreadForm ()
+ app.view.load(keyword || "")
+ },
compose: function(){
app.view = new ComposeView ()
diff --git a/public/assets/js/lib/views/details/commentform.js b/public/assets/js/lib/views/details/commentform.js
index 30671f2..3b82ac7 100644
--- a/public/assets/js/lib/views/details/commentform.js
+++ b/public/assets/js/lib/views/details/commentform.js
@@ -5,7 +5,7 @@ var CommentForm = FormView.extend({
events: {
},
- action: "/api/thread/1/comment",
+ action: "",
initialize: function(){
this.__super__.initialize.call(this)
@@ -26,8 +26,7 @@ var CommentForm = FormView.extend({
return errors.length ? errors : null
},
- success: function(comment){
- this.prependComment(comment)
- this.$("[name=comment]").val("")
+ success: function(){
+ window.location.reload()
}
}) \ No newline at end of file
diff --git a/public/assets/js/lib/views/details/index.js b/public/assets/js/lib/views/details/index.js
index 0a40dbc..25ae020 100644
--- a/public/assets/js/lib/views/details/index.js
+++ b/public/assets/js/lib/views/details/index.js
@@ -23,7 +23,7 @@ var DetailsView = View.extend({
populate: function(data){
var thread = data.thread
$("h1").html(thread.title)
- $(".subtitle").show().html(metadata(thread))
+ $(".subtitle").show().html("<a href='/'>&lt; Home</a> | " + metadata(thread))
this.form.load(data.thread)
this.comments.load(data.comments)
this.files.load(data.files)
diff --git a/public/assets/js/lib/views/index/lastlog.js b/public/assets/js/lib/views/index/lastlog.js
index 0fed101..fe50e0f 100644
--- a/public/assets/js/lib/views/index/lastlog.js
+++ b/public/assets/js/lib/views/index/lastlog.js
@@ -23,7 +23,7 @@ var LastLog = View.extend({
},
parse: function(user){
- if (Date.now()/1000 - user.lastseen > 86400 * 14 *10000) return ''
+ if (Date.now()/1000 - user.lastseen > 86400 * 5 *10) return ''
var t = this.template
.replace(/{{username}}/g, user.username)
.replace(/{{age}}/g, get_age(user.lastseen) )
diff --git a/public/assets/js/lib/views/index/threadform.js b/public/assets/js/lib/views/index/threadform.js
new file mode 100644
index 0000000..2ea6988
--- /dev/null
+++ b/public/assets/js/lib/views/index/threadform.js
@@ -0,0 +1,53 @@
+var ThreadForm = FormView.extend({
+
+ el: "#thread_form",
+
+ events: {
+ },
+
+ action: "/api/thread",
+
+ initialize: function(){
+ this.__super__.initialize.call(this)
+ this.template = this.$(".template").html()
+ },
+
+ load: function(selected_keyword){
+ $.get("/api/keywords", function(data){
+ var tags = {}
+ data.keywords.forEach(keyword => {
+ var kw = keyword.keyword
+ var opt = document.createElement('option')
+ opt.value = kw
+ opt.innerHTML = kw
+ if (selected_keyword === kw) {
+ opt.setAttribute("selected", "selected")
+ }
+ tags[kw] = opt
+ })
+ var sorted = Object.keys(tags).sort().map(kw => tags[kw])
+ this.$('[name=keyword]').append(sorted)
+ }.bind(this))
+ },
+
+ validate: function(){
+ var errors = []
+ var title = this.$("[name=title]").val()
+ if (! title || ! title.length) {
+ errors.push("Please title your post.")
+ }
+ var comment = this.$("[name=comment]").val()
+ var files = this.$("[name=files]").val()
+ if ((! comment || ! comment.length) && ! files) {
+ errors.push("Please enter a comment.")
+ }
+ return errors.length ? errors : null
+ },
+
+ success: function(data){
+ if (data.error) {
+ return alert(data.error)
+ }
+ window.location.href = "/details/" + data.id
+ }
+}) \ No newline at end of file
diff --git a/public/assets/js/vendor/view/formview.js b/public/assets/js/vendor/view/formview.js
index 2c54d3e..485db7a 100644
--- a/public/assets/js/vendor/view/formview.js
+++ b/public/assets/js/vendor/view/formview.js
@@ -13,7 +13,6 @@ var FormView = View.extend({
}
this.$form = this.$("form")
this.$errors = this.$(".errors")
- this.$errorList = this.$(".errorList")
},
reset: function(){
@@ -22,9 +21,9 @@ var FormView = View.extend({
showErrors: function(errors){
if (errors && errors.length) {
- this.$errorList.empty();
+ this.$errors.empty();
for (var i in errors) {
- this.$errorList.append('<div>' + errors[i] + '</div>');
+ this.$errors.append('<div>' + errors[i] + '</div>');
}
this.$errors.css("opacity", 1.0);
setTimeout(function(){
diff --git a/views/pages/post.ejs b/views/pages/post.ejs
new file mode 100644
index 0000000..2889905
--- /dev/null
+++ b/views/pages/post.ejs
@@ -0,0 +1,25 @@
+<% include ../partials/header %>
+
+<div id="content">
+
+<table id="thread_form">
+ <tr>
+ <td>
+ <form>
+ <input type="text" name="title" placeholder="Title">
+ <textarea name="comment" placeholder="Enter your comment"></textarea><br>
+ <div class="inputs">
+ <input name="files" type="file" multiple>
+ <select name="keyword" id="keywords">
+ </select>
+ <input type="submit" value="POST" />
+ </div>
+ <div class="errors"></div>
+ </form>
+ </td>
+ </tr>
+</table>
+
+</div>
+
+<% include ../partials/footer %>
diff --git a/views/partials/comments.ejs b/views/partials/comments.ejs
index 6226a61..80f1b3c 100644
--- a/views/partials/comments.ejs
+++ b/views/partials/comments.ejs
@@ -26,7 +26,7 @@
<tr>
<td>
<form>
- <textarea name="comment"></textarea><br>
+ <textarea name="comment" placeholder="Enter your comment"></textarea><br>
<input type="file" multiple>
<input type="submit" value="POST" />
</form>
diff --git a/views/partials/metadata.ejs b/views/partials/metadata.ejs
index 956ec18..67526db 100644
--- a/views/partials/metadata.ejs
+++ b/views/partials/metadata.ejs
@@ -1,5 +1,5 @@
<script type="text/html" class="metadata_template">
- Posted by {{ username }}
+ Posted by <a href="/profile/{{username}}">{{ username }}</a>
on {{ date }} {{ time }}
&middot;
Last active {{ active }}
diff --git a/views/partials/scripts.ejs b/views/partials/scripts.ejs
index 2786fa8..5bb7049 100644
--- a/views/partials/scripts.ejs
+++ b/views/partials/scripts.ejs
@@ -18,6 +18,7 @@
<script src="/assets/js/lib/views/index/lastlog.js"></script>
<script src="/assets/js/lib/views/index/hootbox.js"></script>
<script src="/assets/js/lib/views/index/threadbox.js"></script>
+<script src="/assets/js/lib/views/index/threadform.js"></script>
<script src="/assets/js/lib/views/search/results.js"></script>