per-thread user IDs AND preview post truncation to 16 line and 1000 chars.

merge-requests/208/head
fatchan 5 years ago
parent 9afa0a65cc
commit 7bafb670bf
  1. 11
      controllers/api.js
  2. 20
      models/api/make-post.js
  3. 24
      static/css/style.css
  4. 2
      views/includes/postform.pug
  5. 22
      views/mixins/post.pug
  6. 9
      views/pages/board.pug
  7. 5
      views/pages/thread.pug

@ -13,14 +13,21 @@ const express = require('express')
/*
(async () => {
await Boards.deleteIncrement('pol');
await Boards.deleteIncrement('b');
await Posts.deleteAll('pol');
await Posts.deleteAll('b');
await Boards.deleteAll();
await Boards.insertOne({
_id: 'pol',
name: 'Politically Incorrect',
description: 'Political posts go here.',
})
await Boards.insertOne({
_id: 'b',
name: 'random',
name: 'Random',
description: 'post anything here',
})
await Posts.deleteAll('b');
})();
*/

@ -2,6 +2,9 @@
const uuidv4 = require('uuid/v4')
, path = require('path')
, util = require('util')
, crypto = require('crypto')
, randomBytes = util.promisify(crypto.randomBytes)
, uploadDirectory = require(__dirname+'/../../helpers/uploadDirectory.js')
, Posts = require(__dirname+'/../../db-models/posts.js')
, fileUpload = require(__dirname+'/../../helpers/files/file-upload.js')
@ -12,17 +15,19 @@ const uuidv4 = require('uuid/v4')
module.exports = async (req, res, numFiles) => {
// check if this is responding to an existing thread
let salt;
if (req.body.thread) {
let thread;
try {
thread = await Posts.getThread(req.params.board, req.body.thread);
thread = await Posts.getPost(req.params.board, req.body.thread);
} catch (err) {
console.error(err);
return res.status(500).json({ 'message': 'Error fetching from DB' });
}
if (!thread) {
if (!thread || thread.thread != null) {
return res.status(400).json({ 'message': 'thread does not exist' })
}
salt = thread.salt;
}
let files = [];
@ -71,6 +76,10 @@ module.exports = async (req, res, numFiles) => {
}
}
if (!salt) {
salt = (await randomBytes(128)).toString('hex');
}
const data = {
'name': req.body.name || 'Anonymous',
'subject': req.body.subject || '',
@ -78,9 +87,14 @@ module.exports = async (req, res, numFiles) => {
'message': req.body.message || '',
'thread': req.body.thread || null,
'password': req.body.password || '',
'files': files
'files': files,
'salt': !req.body.thread ? salt : '',
};
const ip = req.headers['x-real-ip'] || req.connection.remoteAddress;
data.userId = crypto.createHash('sha256').update(salt + ip + req.params.board).digest('hex').substring(0, 6);
const post = await Posts.insertOne(req.params.board, data)
const redirect = '/' + req.params.board + '/thread/' + (req.body.thread || post.insertedId);

@ -9,6 +9,10 @@ body {
margin: 0;
}
blockquote {
word-break: break-all;
}
span {
margin-right: 5px;
}
@ -24,13 +28,21 @@ input, textarea {
font-size: 10pt;
border-radius: 3px;
max-width:100%;
border: none;
margin: 2px;
padding: 5px;
}
.form-post-wrapper {
.form-wrapper {
align-items: center;
margin: 10px 0;
}
.delete-wrapper {
align-items: center;
flex-direction: row;
}
.form-post {
display: flex;
flex-direction: column;
@ -129,7 +141,7 @@ input textarea {
}
.navbar {
border-bottom: 1px solid gray;
border-bottom: 1px solid lightgray;
margin: 0;
position: fixed;
width: 100%;
@ -151,14 +163,14 @@ input textarea {
}
.footer {
border-top: 1px solid gray;
border-top: 1px solid lightgray;
text-align: center;
flex-shrink: 0;
margin-top: auto;
}
table, th, td {
border-bottom: 1px solid gray;
border-bottom: 1px solid lightgray;
border-collapse: collapse;
}
@ -175,6 +187,10 @@ th, td {
padding: 5px;
}
hr {
color: lightgray;
}
@media only screen and (max-width: 800px) {
input {

@ -1,4 +1,4 @@
section.form-post-wrapper
section.form-wrapper
form.form-post(action='/api/board/'+board._id, enctype='multipart/form-data', method='POST')
input(type='hidden' name='_csrf' value=csrf)

@ -1,4 +1,4 @@
mixin post(board, post)
mixin post(board, post, truncate)
article(class='post-container '+(post.thread ? '' : 'op'))
header.post-info
input.post-check(type='checkbox', name='checked[]' value=post._id)
@ -6,6 +6,7 @@ mixin post(board, post)
span.post-subject #{post.subject}
span.post-name #{post.name}
span #{post.date.toLocaleString()}
span.user-id(style=`background: #${post.userId}`) #{post.userId}
if post.thread == null
span: a(href=`/${board._id}/thread/${post._id}`) ##{post._id}
else
@ -22,5 +23,22 @@ mixin post(board, post)
a(target='_blank' href='/img/'+file.filename)
object(data='/img/thumb-'+file.filename type=file.mimetype)
if post.message
blockquote.post-message(style='white-space: pre-wrap;') #{post.message}
if truncate
-
const splitPost = post.message.split('\n');
const messageLines = splitPost.length;
const postLength = post.message.length;
let truncatedMessage = post.mesage;
let truncated = false;
if (messageLines > 16 || post.message.length > 1000) {
truncatedMessage = splitPost.slice(0, 16).join('\n').substring(0, 1000);
truncated = true;
}
if truncated
blockquote.post-message(style='white-space: pre-wrap;') #{truncatedMessage}
p Message too long. #[a(href=`/${board._id}/thread/${post.thread == null ? post._id : post.thread}#${post._id}`) Click here] to view the full text.
else
blockquote.post-message(style='white-space: pre-wrap;') #{post.message}
else
blockquote.post-message(style='white-space: pre-wrap;') #{post.message}

@ -16,9 +16,10 @@ block content
hr(size=1)
for thread in threads
section.thread(id=thread._id)
+post(board, thread)
+post(board, thread, true)
for post in thread.replies
+post(board, post)
+post(board, post, true)
hr(size=1)
input#password(type='password', name='password', placeholder='password (for deletion)' autocomplete='off')
input(type='submit', value='delete')
section.delete-wrapper
input#password(type='password', name='password', placeholder='password (for deletion)' autocomplete='off')
input(type='submit', value='delete')

@ -21,8 +21,9 @@ block content
for post in thread.replies
+post(board, post)
hr(size=1)
input#password(type='password', name='password', placeholder='password (for deletion)' autocomplete='off')
input(type='submit', value='delete')
section.delete-wrapper
input#password(type='password', name='password', placeholder='password (for deletion)' autocomplete='off')
input(type='submit', value='delete')

Loading…
Cancel
Save