good enough styling for now

merge-requests/208/head
fatchan 5 years ago
parent b696653e73
commit a313426e2a
  1. 96
      controllers/api.js
  2. 6
      controllers/frontend.js
  3. 41
      models/boards.js
  4. 16
      models/posts.js
  5. 35
      static/css/style.css
  6. 2
      views/includes/footer.pug
  7. 6
      views/includes/navbar.pug
  8. 16
      views/includes/postform.pug
  9. 11
      views/mixins/post.pug
  10. 2
      views/pages/board.pug
  11. 3
      views/pages/thread.pug

@ -3,33 +3,73 @@
const express = require('express')
, router = express.Router()
, utils = require('../utils.js')
, { check, validationResult } = require('express-validator/check')
, Posts = require(__dirname+'/../models/posts.js')
, Boards = require(__dirname+'/../models/boards.js');
/*
roughly:
- GET /api/board/:board/catalog -> all threads (catalog)
- GET /api/board/:board/recent/:page? -> recent posts per page (board homepage)
- GET /api/board/:board/thread/:thread -> get all posts in a thread
- GET /board/:board/catalog -> all threads (catalog)
- GET /board/:board/recent/:page? -> recent posts per page (board homepage)
- GET /board/:board/thread/:thread -> get all posts in a thread
- POST /api/board/:board -> make a new thread
- POST /api/board/:board/thread/:thread -> make a new post in a thread
- POST /board/:board -> make a new thread
- POST /board/:board/thread/:thread -> make a new post in a thread
- DELETE /api/board/:board/post/:id -> delete a post
- DELETE /board/:board/post/:id -> delete a post
*/
// make new post
router.post('/api/board/:board', Boards.exists, async (req, res, next) => {
router.post('/board/:board', Boards.exists, [
check('author').optional(),
check('subject').optional(),
check('thread').optional(),
check('content').not().isEmpty().withMessage('missing message content'),
], async (req, res, next) => {
//return array of errors about bad post
const errors = validationResult(req)
if (!errors.isEmpty()) {
return res.json({errors:errors.array()})
}
//ghetto setting to 0 so expres validator doesnt skip null value. needs looking into.
if (req.body.thread) {
let thread;
try {
thread = await Posts.getThread(req.params.board, req.body.thread);
} catch (err) {
return res.status(500).json({ 'message': 'Error fetching from DB' });
}
if (!thread) {
return res.status(400).json({ 'message': 'thread does not exist' })
}
}
//TODO: handle file uploads instead of just doing nothing
//add the post
const post = await Posts.insertOne(req.params.board, {
'author': req.body.author || 'Anonymous',
'subject': req.body.subject || '',
'date': new Date(),
'content': req.body.content,
'thread': req.body.thread || null
})
const redirect = '/' + req.params.board + '/thread/' + (req.body.thread || post.insertedId);
return res.redirect(redirect)
});
// delete a post
router.delete('/api/board/:board/post/:id', Boards.exists, async (req, res, next) => {
router.delete('/board/:board/post/:id(\\d+)', Boards.exists, async (req, res, next) => {
});
// get recent threads and preview posts
router.get('/api/board/:board/recent/:page', Boards.exists, async (req, res, next) => {
router.get('/board/:board/recent/:page(\\d+)?', Boards.exists, async (req, res, next) => {
//get the recently bumped thread & preview posts
let threads;
@ -48,12 +88,12 @@ router.get('/api/board/:board/recent/:page', Boards.exists, async (req, res, nex
});
// get a thread
router.get('/api/board/:board/thread/:thread([a-f\d]{24})', Boards.exists, async (req, res, next) => {
router.get('/board/:board/thread/:id(\\d+)', Boards.exists, async (req, res, next) => {
//get the recently bumped thread & preview posts
let thread;
try {
thread = await Posts.getThread(req.params.board, req.params.thread);
thread = await Posts.getThread(req.params.board, req.params.id);
} catch (err) {
return res.status(500).json({ 'message': 'Error fetching from DB' });
}
@ -67,7 +107,7 @@ router.get('/api/board/:board/thread/:thread([a-f\d]{24})', Boards.exists, async
});
// get array of threads (catalog)
router.get('/api/board/:board/catalog', Boards.exists, async (req, res, next) => {
router.get('/board/:board/catalog', Boards.exists, async (req, res, next) => {
//get the recently bumped thread & preview posts
let data;
@ -86,23 +126,24 @@ router.get('/api/board/:board/catalog', Boards.exists, async (req, res, next) =>
});
//get list of boards
router.get('/api/boards', Boards.exists, async (req, res, next) => {
router.get('/boards', Boards.exists, async (req, res, next) => {
//get a list of boards
let boards;
try {
boards = await Boards.find();
} catch (err) {
//get a list of boards
let boards;
try {
boards = await Boards.find();
} catch (err) {
return res.status(500).json({ 'message': 'Error fetching from DB' })
}
}
//render the page
res.json(boards)
//render the page
res.json(boards)
});
/*
(async () => {
await Boards.deleteIncrement('b');
await Boards.deleteAll();
await Boards.insertOne({
_id: 'b',
@ -110,26 +151,27 @@ router.get('/api/boards', Boards.exists, async (req, res, next) => {
description: 'post anything here',
})
await Posts.deleteAll('b');
for (let i = 0; i < 5; i++) {
for (let i = 0; i < 3; i++) {
const thread = await Posts.insertOne('b', {
'author': 'Anonymous',
'title': 'post title',
'subject': 'subject',
'date': new Date(),
'content': Math.random().toString(36).replace(/[^a-z]+/g, ''),
'thread': null
})
for (let j = 0; j < 30; j++) {
for (let j = 0; j < 5; j++) {
await new Promise(resolve => {setTimeout(resolve, 500)})
const post = await Posts.insertOne('b', {
'author': 'Anonymous',
'title': 'post title',
'subject': 'subject',
'date': new Date(),
'content': Math.random().toString(36).replace(/[^a-z]+/g, ''),
'thread': thread.insertedId
'thread': thread.insertedId + ''
})
}
}
})();
*/
module.exports = router;

@ -19,7 +19,7 @@ roughly:
*/
// board page/recents
router.get('/:board/:page?', Boards.exists, async (req, res, next) => {
router.get('/:board/:page(\\d+)?', Boards.exists, async (req, res, next) => {
//get the recently bumped thread & preview posts
let threads;
@ -38,12 +38,12 @@ router.get('/:board/:page?', Boards.exists, async (req, res, next) => {
});
// thread view page
router.get('/:board/thread/:thread([a-f\\d]{24})', Boards.exists, async (req, res, next) => {
router.get('/:board/thread/:id(\\d+)', Boards.exists, async (req, res, next) => {
//get the recently bumped thread & preview posts
let thread;
try {
thread = await Posts.getThread(req.params.board, req.params.thread);
thread = await Posts.getThread(req.params.board, req.params.id);
} catch (err) {
return next(err);
}

@ -42,4 +42,45 @@ module.exports = {
},
getNextId: async (board) => {
const increment = await db.collection('counters').findOneAndUpdate(
{
'_id': board
},
{
'$inc': {
'sequence_value': 1
}
},
{
'upsert': true
}
);
// faster than toString()
return increment.value.sequence_value + '';
},
deleteIncrement: async (board) => {
await db.collection('counters').findOneAndUpdate(
{
'_id': board
},
{
'$set': {
'sequence_value': 1
}
},
{
'upsert': true
}
);
return;
},
}

@ -1,6 +1,7 @@
'use strict';
const Mongo = require(__dirname+'/../helpers/db.js')
, Boards = require(__dirname+'/boards.js')
, db = Mongo.client.db('posts');
module.exports = {
@ -36,10 +37,10 @@ module.exports = {
// get thread post and potential replies concurrently
const data = await Promise.all([
db.collection(board).findOne({
'_id': Mongo.ObjectId(id)
'_id': id
}),
db.collection(board).find({
'thread': Mongo.ObjectId(id)
'thread': id
}).sort({
'_id': 1
}).toArray()
@ -68,7 +69,7 @@ module.exports = {
// get a post
return db.collection(board).findOne({
'_id': Mongo.ObjectId(id)
'_id': id
});
},
@ -80,12 +81,19 @@ module.exports = {
await db.collection(board).updateOne({
'_id': data.thread
}, {
$set: {
'$set': {
'bumped': Date.now()
}
})
}
data._id = await Boards.getNextId(board);
//this is an OP, so set the bump date so its pushed to the top
if (data.thread == null) {
data.bumped = Date.now()
}
return db.collection(board).insertOne(data);
},

@ -9,8 +9,20 @@ body {
margin: 0;
}
input, textarea {
display: block;
font-family: arial, helvetica, sans-serif;
font-size: 10pt;
border-radius: 3px;
}
input textares {
padding: 8px;
}
.container {
margin: 5px;
margin-top: 57px;
}
.board-title {
@ -22,6 +34,7 @@ body {
}
.post-container {
margin-top: 5px;
margin-left: 15px;
padding: 5px;
background: #D6DAF0;
@ -35,17 +48,29 @@ body {
.navbar {
border-bottom: 1px solid black;
margin: 0;
padding: 5px;
line-height: 50px;
height: 50px;
position: fixed;
width: 100%;
background: #eef2ff;
}
.nav-item {
list-style: none;
display: inline;
padding-left: 20px;
line-height: 50px;
font-size: 14pt;
text-decoration: none;
float: left;
background: #D6DAF0;
padding-left: 10px;
padding-right: 10px;
}
.nav-item:hover {
box-shadow: inset 0 0 100px 100px rgba(255,255,255,.1);
}
.footer {
line-height: 50px;
border-top: 1px solid black;
text-align: center;
flex-shrink: 0;
margin-top: auto;

@ -1,2 +1,2 @@
.footer
p footer
p not lynxchan ™

@ -1,3 +1,3 @@
ul.navbar
li.nav-item: a(href='/') Home
li.nav-item: a(href='/login') Mod Login
.navbar
a.nav-item(href='/') Home
a.nav-item(href='/login') Mod Login

@ -0,0 +1,16 @@
p make a post:
form.form-post(action='/api/board/'+board._id, enctype='multipart/form-data', method='POST')
input(type='hidden' name='_csrf' value=csrf)
input(type='hidden' name='thread' value=thread != null ? thread._id : null)
input#title(type='text', name='subject', placeholder='subject')
input#name(type='text', name='author', placeholder='name')
textarea#content(name='content', rows='8', cols='50', placeholder='message')
input#file(type='file', name='files' multiple)
input(type='submit', value='submit')

@ -1,10 +1,11 @@
mixin post(board, post)
div(class='post-container '+(post.thread ? '' : 'op'))
if post.thread == null
a(href=`/${board._id}/thread/${post._id}`) #{post._id}
else
a(href=`/${board._id}/thread/${post.thread}#${post._id}`) #{post._id}
span #{post.subject}
span , #{post.author}
span , #{post.date.toLocaleString()}
p #{post.title}
span , Post
if post.thread == null
a(href=`/${board._id}/thread/${post._id}`) ##{post._id}
else
a(href=`/${board._id}/thread/${post.thread}#${post._id}`) ##{post._id}
p #{post.content}

@ -7,6 +7,8 @@ block head
block content
span #{board.name} - #{board.description}
hr(size=1)
include ../includes/postform.pug
hr(size=1)
for thread in threads
+post(board, thread)
for post in thread.replies

@ -7,7 +7,8 @@ block head
block content
a(href='/'+board._id) Back to /#{board._id}/
hr(size=1)
include ../includes/postform.pug
hr(size=1)
+post(board, thread)
for post in thread.replies
+post(board, post)
hr(size=1)

Loading…
Cancel
Save