mirror of https://gitgud.io/fatchan/jschan.git
Merge pull request #27 from fatchan/html-generate
commit
2ccafcdb06
59 changed files with 975 additions and 503 deletions
@ -0,0 +1,97 @@ |
|||||||
|
'use strict'; |
||||||
|
|
||||||
|
const Posts = require(__dirname+'/db/posts.js') |
||||||
|
, Boards = require(__dirname+'/db/boards.js') |
||||||
|
, uploadDirectory = require(__dirname+'/helpers/uploadDirectory.js') |
||||||
|
, render = require(__dirname+'/helpers/render.js'); |
||||||
|
|
||||||
|
module.exports = { |
||||||
|
|
||||||
|
buildCatalog: async (board) => { |
||||||
|
const threads = await Posts.getCatalog(board._id); |
||||||
|
return render(`${board._id}/catalog.html`, 'catalog.pug', { |
||||||
|
board, |
||||||
|
threads |
||||||
|
}); |
||||||
|
}, |
||||||
|
|
||||||
|
buildThread: async (threadId, board) => { |
||||||
|
//console.log('building thread', `${board._id || board}/thread/${threadId}.html`);
|
||||||
|
if (!board._id) { |
||||||
|
board = await Boards.findOne(board); |
||||||
|
} |
||||||
|
const thread = await Posts.getThread(board._id, threadId) |
||||||
|
if (!thread) { |
||||||
|
return; //this thread may have been an OP that was deleted during a rebuild
|
||||||
|
} |
||||||
|
return render(`${board._id}/thread/${threadId}.html`, 'thread.pug', { |
||||||
|
board, |
||||||
|
thread |
||||||
|
}); |
||||||
|
}, |
||||||
|
|
||||||
|
buildBoard: async (board, page, maxPage=null) => { |
||||||
|
//console.log('building board page', `${board._id}/${page === 1 ? 'index' : page}.html`);
|
||||||
|
const threads = await Posts.getRecent(board._id, page); |
||||||
|
if (!maxPage) { |
||||||
|
maxPage = Math.ceil((await Posts.getPages(board._id)) / 10); |
||||||
|
} |
||||||
|
return render(`${board._id}/${page === 1 ? 'index' : page}.html`, 'board.pug', { |
||||||
|
board, |
||||||
|
threads, |
||||||
|
maxPage, |
||||||
|
page |
||||||
|
}); |
||||||
|
}, |
||||||
|
|
||||||
|
//building multiple pages (for rebuilds)
|
||||||
|
buildBoardMultiple: async (board, startpage=1, endpage=10) => { |
||||||
|
const maxPage = Math.ceil((await Posts.getPages(board._id)) / 10); |
||||||
|
if (endpage === 0) { |
||||||
|
//deleted only/all posts, so only 1 page will remain
|
||||||
|
endpage = 1; |
||||||
|
} else if (maxPage < endpage) { |
||||||
|
//else just build up to the max page if it is greater than input page number
|
||||||
|
endpage = maxPage |
||||||
|
} |
||||||
|
const difference = endpage-startpage + 1; //+1 because for single pagemust be > 0
|
||||||
|
const threads = await Posts.getRecent(board._id, startpage, difference*10); |
||||||
|
const buildArray = []; |
||||||
|
for (let i = startpage; i <= endpage; i++) { |
||||||
|
//console.log('multi building board page', `${board._id}/${i === 1 ? 'index' : i}.html`);
|
||||||
|
let spliceStart = (i-1)*10; |
||||||
|
if (spliceStart > 0) { |
||||||
|
spliceStart = spliceStart - 1; |
||||||
|
} |
||||||
|
buildArray.push( |
||||||
|
render(`${board._id}/${i === 1 ? 'index' : i}.html`, 'board.pug', { |
||||||
|
board, |
||||||
|
threads: threads.splice(0,10), |
||||||
|
maxPage, |
||||||
|
page: i, |
||||||
|
}) |
||||||
|
); |
||||||
|
} |
||||||
|
return Promise.all(buildArray); |
||||||
|
}, |
||||||
|
|
||||||
|
buildHomepage: async () => { |
||||||
|
const boards = await Boards.find(); |
||||||
|
return render('index.html', 'home.pug', { |
||||||
|
boards |
||||||
|
}); |
||||||
|
}, |
||||||
|
|
||||||
|
buildChangePassword: () => { |
||||||
|
return render('changepassword.html', 'changepassword.pug'); |
||||||
|
}, |
||||||
|
|
||||||
|
buildLogin: () => { |
||||||
|
return render('login.html', 'login.pug'); |
||||||
|
}, |
||||||
|
|
||||||
|
buildRegister: () => { |
||||||
|
return render('register.html', 'register.pug'); |
||||||
|
}, |
||||||
|
|
||||||
|
} |
@ -1,15 +1,12 @@ |
|||||||
'use strict'; |
'use strict'; |
||||||
|
|
||||||
const path = require('path') |
const remove = require('fs-extra').remove |
||||||
, util = require('util') |
|
||||||
, fs = require('fs') |
|
||||||
, unlink = util.promisify(fs.unlink) |
|
||||||
, uploadDirectory = require(__dirname+'/../../helpers/uploadDirectory.js'); |
, uploadDirectory = require(__dirname+'/../../helpers/uploadDirectory.js'); |
||||||
|
|
||||||
module.exports = async (filenames, folder) => { |
module.exports = async (filenames, folder) => { |
||||||
|
|
||||||
await Promise.all(filenames.map(async filename => { |
await Promise.all(filenames.map(async filename => { |
||||||
unlink(`${uploadDirectory}${folder}/${filename}`) |
remove(`${uploadDirectory}${folder}/${filename}`) |
||||||
})); |
})); |
||||||
|
|
||||||
} |
} |
||||||
|
@ -0,0 +1,19 @@ |
|||||||
|
'use strict'; |
||||||
|
|
||||||
|
const uploadDirectory = require(__dirname+'/../uploadDirectory.js') |
||||||
|
, gm = require('@tohru/gm'); |
||||||
|
|
||||||
|
module.exports = (file, filename, folder) => { |
||||||
|
|
||||||
|
return new Promise((resolve, reject) => { |
||||||
|
gm(file.tempFilePath) |
||||||
|
.noProfile() |
||||||
|
.write(`${uploadDirectory}${folder}/${filename}`, function (err) { |
||||||
|
if (err) { |
||||||
|
return reject(err); |
||||||
|
} |
||||||
|
return resolve(); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
}; |
@ -1,9 +1,8 @@ |
|||||||
'use strict'; |
'use strict'; |
||||||
|
|
||||||
const configs = require(__dirname+'/../../configs/main.json') |
const uploadDirectory = require(__dirname+'/../uploadDirectory.js'); |
||||||
, uploadDirectory = require(__dirname+'/../uploadDirectory.js'); |
|
||||||
|
|
||||||
module.exports = (req, res, file, filename, folder) => { |
module.exports = (file, filename, folder) => { |
||||||
|
|
||||||
return new Promise((resolve, reject) => { |
return new Promise((resolve, reject) => { |
||||||
file.mv(`${uploadDirectory}${folder}/${filename}`, function (err) { |
file.mv(`${uploadDirectory}${folder}/${filename}`, function (err) { |
@ -0,0 +1,12 @@ |
|||||||
|
'use strict'; |
||||||
|
|
||||||
|
const outputFile = require('fs-extra').outputFile |
||||||
|
, pug = require('pug') |
||||||
|
, path = require('path') |
||||||
|
, uploadDirectory = require(__dirname+'/uploadDirectory.js') |
||||||
|
, templateDirectory = path.join(__dirname+'/../views/pages/'); |
||||||
|
|
||||||
|
module.exports = async (htmlName, templateName, options) => { |
||||||
|
const html = pug.renderFile(`${templateDirectory}${templateName}`, { ...options, cache: true }); |
||||||
|
return outputFile(`${uploadDirectory}html/${htmlName}`, html); |
||||||
|
}; |
@ -1,14 +0,0 @@ |
|||||||
'use strict'; |
|
||||||
|
|
||||||
const util = require('util') |
|
||||||
, fs = require('fs') |
|
||||||
, pug = require('pug') |
|
||||||
, path = require('path') |
|
||||||
, writeFile = util.promisify(fs.writeFile) |
|
||||||
, uploadDirectory = require(__dirname+'/uploadDirectory.js') |
|
||||||
, pugDirectory = path.join(__dirname+'/../views/pages'); |
|
||||||
|
|
||||||
module.exports = async (htmlName, pugName, pugVars) => { |
|
||||||
const html = pug.renderFile(`${pugDirectory}/${pugName}`, pugVars); |
|
||||||
return writeFile(`${uploadDirectory}html/${htmlName}`, html); |
|
||||||
}; |
|
@ -1,26 +1,22 @@ |
|||||||
'use strict'; |
'use strict'; |
||||||
|
|
||||||
const Posts = require(__dirname+'/../../db/posts.js')l |
const Posts = require(__dirname+'/../../db/posts.js') |
||||||
|
, { buildBoard } = require(__dirname+'/../../build.js') |
||||||
|
, uploadDirectory = require(__dirname+'/../../helpers/uploadDirectory.js'); |
||||||
|
|
||||||
module.exports = async (req, res, next) => { |
module.exports = async (req, res, next) => { |
||||||
|
|
||||||
const page = req.params.page === 'index' ? 1 : (req.params.page || 1); |
const page = req.params.page === 'index' ? 1 : req.params.page; |
||||||
let threads; |
|
||||||
let pages; |
|
||||||
try { |
try { |
||||||
pages = Math.ceil((await Posts.getPages(req.params.board)) / 10) |
const maxPage = Math.ceil((await Posts.getPages(req.params.board)) / 10); |
||||||
if (page > pages && pages > 0) { |
if (page > maxPage && maxPage > 0) { |
||||||
return next(); |
return next(); |
||||||
} |
} |
||||||
threads = await Posts.getRecent(req.params.board, page); |
await buildBoard(res.locals.board, page, maxPage); |
||||||
} catch (err) { |
} catch (err) { |
||||||
return next(err); |
return next(err); |
||||||
} |
} |
||||||
|
|
||||||
return res.render('board', { |
return res.sendFile(`${uploadDirectory}html/${req.params.board}/${page === 1 ? 'index' : page}.html`); |
||||||
threads: threads || [], |
|
||||||
pages, |
|
||||||
page, |
|
||||||
}); |
|
||||||
|
|
||||||
} |
} |
||||||
|
@ -1,20 +1,16 @@ |
|||||||
'use strict'; |
'use strict'; |
||||||
|
|
||||||
const Posts = require(__dirname+'/../../db/posts.js'); |
const { buildCatalog } = require(__dirname+'/../../build.js') |
||||||
|
, uploadDirectory = require(__dirname+'/../../helpers/uploadDirectory.js'); |
||||||
|
|
||||||
module.exports = async (req, res, next) => { |
module.exports = async (req, res, next) => { |
||||||
|
|
||||||
// get all threads
|
|
||||||
let threads; |
|
||||||
try { |
try { |
||||||
threads = await Posts.getCatalog(req.params.board); |
await buildCatalog(res.locals.board); |
||||||
} catch (err) { |
} catch (err) { |
||||||
return next(err); |
return next(err); |
||||||
} |
} |
||||||
|
|
||||||
//render the page
|
return res.sendFile(`${uploadDirectory}html/${req.params.board}/catalog.html`); |
||||||
res.render('catalog', { |
|
||||||
threads: threads || [], |
|
||||||
}); |
|
||||||
|
|
||||||
} |
} |
||||||
|
@ -1,8 +1,16 @@ |
|||||||
'use strict'; |
'use strict'; |
||||||
|
|
||||||
module.exports = (req, res, next) => { |
const { buildChangePassword } = require(__dirname+'/../../build.js') |
||||||
|
, uploadDirectory = require(__dirname+'/../../helpers/uploadDirectory.js'); |
||||||
|
|
||||||
//render the page
|
module.exports = async (req, res, next) => { |
||||||
res.render('changepassword'); |
|
||||||
|
try { |
||||||
|
await buildChangePassword(); |
||||||
|
} catch (err) { |
||||||
|
return next(err); |
||||||
|
} |
||||||
|
|
||||||
|
return res.sendFile(`${uploadDirectory}html/changepassword.html`); |
||||||
|
|
||||||
} |
} |
||||||
|
@ -1,17 +1,16 @@ |
|||||||
'use strict'; |
'use strict'; |
||||||
|
|
||||||
const Boards = require(__dirname+'/../../db/boards.js'); |
const { buildHomepage } = require(__dirname+'/../../build.js') |
||||||
|
, uploadDirectory = require(__dirname+'/../../helpers/uploadDirectory.js'); |
||||||
|
|
||||||
module.exports = async (req, res, next) => { |
module.exports = async (req, res, next) => { |
||||||
|
|
||||||
//get a list of boards
|
|
||||||
let boards; |
|
||||||
try { |
try { |
||||||
boards = await Boards.find(); |
await buildHomepage(); |
||||||
} catch (err) { |
} catch (err) { |
||||||
return next(err); |
return next(err); |
||||||
} |
} |
||||||
|
|
||||||
res.render('home', { boards }); |
return res.sendFile(`${uploadDirectory}html/index.html`); |
||||||
|
|
||||||
} |
} |
||||||
|
@ -1,11 +1,16 @@ |
|||||||
'use strict'; |
'use strict'; |
||||||
|
|
||||||
module.exports = (req, res, next) => { |
const { buildLogin } = require(__dirname+'/../../build.js') |
||||||
|
, uploadDirectory = require(__dirname+'/../../helpers/uploadDirectory.js'); |
||||||
|
|
||||||
//render the page
|
module.exports = async (req, res, next) => { |
||||||
res.render('login', { |
|
||||||
csrf: req.csrfToken(), |
try { |
||||||
redirect: req.query.redirect, |
await buildLogin(); |
||||||
}); |
} catch (err) { |
||||||
|
return next(err); |
||||||
|
} |
||||||
|
|
||||||
|
return res.sendFile(`${uploadDirectory}html/login.html`); |
||||||
|
|
||||||
} |
} |
||||||
|
@ -1,10 +1,16 @@ |
|||||||
'use strict'; |
'use strict'; |
||||||
|
|
||||||
module.exports = (req, res, next) => { |
const { buildRegister } = require(__dirname+'/../../build.js') |
||||||
|
, uploadDirectory = require(__dirname+'/../../helpers/uploadDirectory.js'); |
||||||
|
|
||||||
//render the page
|
module.exports = async (req, res, next) => { |
||||||
res.render('register', { |
|
||||||
csrf: req.csrfToken() |
try { |
||||||
}); |
await buildRegister(); |
||||||
|
} catch (err) { |
||||||
|
return next(err); |
||||||
|
} |
||||||
|
|
||||||
|
return res.sendFile(`${uploadDirectory}html/register.html`); |
||||||
|
|
||||||
} |
} |
||||||
|
@ -1,23 +1,16 @@ |
|||||||
'use strict'; |
'use strict'; |
||||||
|
|
||||||
const Posts = require(__dirname+'/../../db/posts.js'); |
const { buildThread } = require(__dirname+'/../../build.js') |
||||||
|
, uploadDirectory = require(__dirname+'/../../helpers/uploadDirectory.js'); |
||||||
|
|
||||||
module.exports = async (req, res, next) => { |
module.exports = async (req, res, next) => { |
||||||
|
|
||||||
//get the recently bumped thread & preview posts
|
|
||||||
let thread; |
|
||||||
try { |
try { |
||||||
thread = await Posts.getThread(req.params.board, req.params.id); |
await buildThread(res.locals.thread.postId, res.locals.board); |
||||||
} catch (err) { |
} catch (err) { |
||||||
return next(err); |
return next(err); |
||||||
} |
} |
||||||
|
|
||||||
if (!thread) { |
return res.sendFile(`${uploadDirectory}html/${req.params.board}/thread/${req.params.id}.html`); |
||||||
return res.status(404).render('404'); |
|
||||||
} |
|
||||||
|
|
||||||
//render the page
|
|
||||||
res.render('thread', { |
|
||||||
thread |
|
||||||
}); |
|
||||||
} |
} |
||||||
|
@ -1,57 +1,56 @@ |
|||||||
label.toggle-label Toggle Post Actions |
details.toggle-label |
||||||
input.toggle(type='checkbox') |
summary Show Post Actions |
||||||
.action-wrapper.togglable |
.actions |
||||||
.actions |
h4.no-m-p Actions: |
||||||
h4.no-m-p Actions: |
label |
||||||
label |
input.post-check(type='checkbox', name='delete' value=1) |
||||||
input.post-check(type='checkbox', name='delete' value=1) |
| Delete |
||||||
| Delete |
label |
||||||
label |
input.post-check(type='checkbox', name='delete_file' value=1) |
||||||
input.post-check(type='checkbox', name='delete_file' value=1) |
| Delete File Only |
||||||
| Delete File Only |
label |
||||||
label |
input.post-check(type='checkbox', name='spoiler' value=1) |
||||||
input.post-check(type='checkbox', name='spoiler' value=1) |
| Spoiler Images |
||||||
| Spoiler Images |
label |
||||||
label |
input#password(type='text', name='password', placeholder='post password' autocomplete='off') |
||||||
input#password(type='text', name='password', placeholder='post password' autocomplete='off') |
label |
||||||
label |
input.post-check(type='checkbox', name='report' value=1) |
||||||
input.post-check(type='checkbox', name='report' value=1) |
| Report |
||||||
| Report |
label |
||||||
label |
input.post-check(type='checkbox', name='global_report' value=1) |
||||||
input.post-check(type='checkbox', name='global_report' value=1) |
| Global Report |
||||||
| Global Report |
label |
||||||
label |
input#report(type='text', name='report_reason', placeholder='report reason' autocomplete='off') |
||||||
input#report(type='text', name='report_reason', placeholder='report reason' autocomplete='off') |
.actions |
||||||
.actions |
h4.no-m-p Mod Actions: |
||||||
h4.no-m-p Mod Actions: |
label |
||||||
label |
input.post-check(type='checkbox', name='delete_ip_board' value=1) |
||||||
input.post-check(type='checkbox', name='delete_ip_board' value=1) |
| Delete from IP on board |
||||||
| Delete from IP on board |
label |
||||||
label |
input.post-check(type='checkbox', name='delete_ip_global' value=1) |
||||||
input.post-check(type='checkbox', name='delete_ip_global' value=1) |
| Delete from IP globally |
||||||
| Delete from IP globally |
label |
||||||
label |
input.post-check(type='checkbox', name='sticky' value=1) |
||||||
input.post-check(type='checkbox', name='sticky' value=1) |
| Sticky |
||||||
| Sticky |
label |
||||||
label |
input.post-check(type='checkbox', name='lock' value=1) |
||||||
input.post-check(type='checkbox', name='lock' value=1) |
| Lock |
||||||
| Lock |
label |
||||||
label |
input.post-check(type='checkbox', name='sage' value=1) |
||||||
input.post-check(type='checkbox', name='sage' value=1) |
| Sage |
||||||
| Sage |
label |
||||||
label |
input.post-check(type='checkbox', name='ban' value=1) |
||||||
input.post-check(type='checkbox', name='ban' value=1) |
| Ban Poster |
||||||
| Ban Poster |
label |
||||||
label |
input.post-check(type='checkbox', name='global_ban' value=1) |
||||||
input.post-check(type='checkbox', name='global_ban' value=1) |
| Global Ban Poster |
||||||
| Global Ban Poster |
label |
||||||
label |
input.post-check(type='checkbox', name='preserve_post' value=1) |
||||||
input.post-check(type='checkbox', name='preserve_post' value=1) |
| Show Post In Ban |
||||||
| Show Post In Ban |
label |
||||||
label |
input#report(type='text', name='ban_reason', placeholder='ban reason' autocomplete='off') |
||||||
input#report(type='text', name='ban_reason', placeholder='ban reason' autocomplete='off') |
.actions |
||||||
.actions |
h4.no-m-p Captcha: |
||||||
h4.no-m-p Captcha: |
img.captcha(src='/captcha' width=200 height=80) |
||||||
img.captcha(src='/captcha' width=200 height=80) |
input#captcha(type='text', name='captcha', autocomplete='off' placeholder='captcha text' maxlength='6') |
||||||
input#captcha(type='text', name='captcha', autocomplete='off' placeholder='captcha text' maxlength='6') |
input(type='submit', value='submit') |
||||||
input(type='submit', value='submit') |
|
||||||
|
@ -1,32 +1,28 @@ |
|||||||
label.toggle-label Toggle Post Actions |
details.toggle-label |
||||||
input.toggle(type='checkbox') |
summary Show Post Actions |
||||||
.action-wrapper.togglable |
.actions |
||||||
.actions |
h4.no-m-p Actions: |
||||||
h4.no-m-p Actions: |
label |
||||||
label |
input.post-check(type='checkbox', name='delete' value=1) |
||||||
input.post-check(type='checkbox', name='delete' value=1) |
| Delete |
||||||
| Delete |
label |
||||||
label |
input.post-check(type='checkbox', name='delete_file' value=1) |
||||||
input.post-check(type='checkbox', name='delete_file' value=1) |
| Delete File Only |
||||||
| Delete File Only |
label |
||||||
label |
input.post-check(type='checkbox', name='spoiler' value=1) |
||||||
input.post-check(type='checkbox', name='spoiler' value=1) |
| Spoiler Images |
||||||
| Spoiler Images |
label |
||||||
label |
input.post-check(type='checkbox', name='delete_ip_global' value=1) |
||||||
input#report(type='text', name='report_reason', placeholder='report reason' autocomplete='off') |
| Delete from IP globally |
||||||
label |
label |
||||||
input.post-check(type='checkbox', name='delete_ip_global' value=1) |
input.post-check(type='checkbox', name='global_dismiss' value=1) |
||||||
| Delete from IP globally |
| Dismiss Global Reports |
||||||
label |
label |
||||||
input.post-check(type='checkbox', name='global_dismiss' value=1) |
input.post-check(type='checkbox', name='global_ban' value=1) |
||||||
| Dismiss Global Reports |
| Global Ban Poster |
||||||
label |
label |
||||||
input.post-check(type='checkbox', name='global_ban' value=1) |
input.post-check(type='checkbox', name='preserve_post' value=1) |
||||||
| Global Ban Poster |
| Show Post In Ban |
||||||
label |
label |
||||||
input.post-check(type='checkbox', name='preserve_post' value=1) |
input#ban_reason(type='text', name='ban_reason', placeholder='ban reason' autocomplete='off') |
||||||
| Show Post In Ban |
input(type='submit', value='submit') |
||||||
label |
|
||||||
input#ban_reason(type='text', name='ban_reason', placeholder='ban reason' autocomplete='off') |
|
||||||
input(type='submit', value='submit') |
|
||||||
|
|
||||||
|
@ -1,36 +1,39 @@ |
|||||||
label.toggle-label Toggle Post Actions |
details.toggle-label |
||||||
input.toggle(type='checkbox') |
summary Show Post Actions |
||||||
.action-wrapper.togglable |
.actions |
||||||
.actions |
h4.no-m-p Actions: |
||||||
h4.no-m-p Actions: |
label |
||||||
label |
input.post-check(type='checkbox', name='delete' value=1) |
||||||
input.post-check(type='checkbox', name='delete' value=1) |
| Delete |
||||||
| Delete |
label |
||||||
label |
input.post-check(type='checkbox', name='delete_file' value=1) |
||||||
input.post-check(type='checkbox', name='delete_file' value=1) |
| Delete File Only |
||||||
| Delete File Only |
label |
||||||
label |
input.post-check(type='checkbox', name='spoiler' value=1) |
||||||
input.post-check(type='checkbox', name='spoiler' value=1) |
| Spoiler Images |
||||||
| Spoiler Images |
label |
||||||
label |
input.post-check(type='checkbox', name='global_report' value=1) |
||||||
input.post-check(type='checkbox', name='delete_ip_board' value=1) |
| Global Report |
||||||
| Delete from IP on board |
label |
||||||
label |
input#report(type='text', name='report_reason', placeholder='report reason' autocomplete='off') |
||||||
input.post-check(type='checkbox', name='delete_ip_global' value=1) |
label |
||||||
| Delete from IP globally |
input.post-check(type='checkbox', name='delete_ip_board' value=1) |
||||||
label |
| Delete from IP on board |
||||||
input.post-check(type='checkbox', name='dismiss' value=1) |
label |
||||||
| Dismiss Reports |
input.post-check(type='checkbox', name='delete_ip_global' value=1) |
||||||
label |
| Delete from IP globally |
||||||
input.post-check(type='checkbox', name='ban' value=1) |
label |
||||||
| Ban Poster |
input.post-check(type='checkbox', name='dismiss' value=1) |
||||||
label |
| Dismiss Reports |
||||||
input.post-check(type='checkbox', name='global_ban' value=1) |
label |
||||||
| Global Ban Poster |
input.post-check(type='checkbox', name='ban' value=1) |
||||||
label |
| Ban Poster |
||||||
input.post-check(type='checkbox', name='preserve_post' value=1) |
label |
||||||
| Show Post In Ban |
input.post-check(type='checkbox', name='global_ban' value=1) |
||||||
label |
| Global Ban Poster |
||||||
input#ban_reason(type='text', name='ban_reason', placeholder='ban reason' autocomplete='off') |
label |
||||||
input(type='submit', value='submit') |
input.post-check(type='checkbox', name='preserve_post' value=1) |
||||||
|
| Show Post In Ban |
||||||
|
label |
||||||
|
input#ban_reason(type='text', name='ban_reason', placeholder='ban reason' autocomplete='off') |
||||||
|
input(type='submit', value='submit') |
||||||
|
@ -1,6 +1,6 @@ |
|||||||
section.board-header |
section.board-header |
||||||
if board.banners.length > 0 |
object.board-banner(data=`/banners?board=${board._id}` width='300' height='100') |
||||||
object.board-banner(data=`/banners?board=${board._id}` width='300' height='100') |
br |
||||||
a.no-decoration(href=`/${board._id}/index`) |
a.no-decoration(href=`/${board._id}/index.html`) |
||||||
h1.board-title /#{board._id}/ - #{board.name} |
h1.board-title /#{board._id}/ - #{board.name} |
||||||
h4.board-description #{board.description} |
h4.board-description #{board.description} |
||||||
|
@ -1,2 +1,2 @@ |
|||||||
.footer |
.footer |
||||||
a(href='https://github.com/fatchan/jschan/') not lynxchan ™ |
a(href='https://github.com/fatchan/jschan/') not lynxchan™ |
||||||
|
@ -1,8 +1,5 @@ |
|||||||
nav.navbar |
nav.navbar |
||||||
a.nav-item(href='/') Home |
a.nav-item(href='/') Home |
||||||
a.nav-item.right(href='/logout') Logout |
a.nav-item.right(href='/logout') Logout |
||||||
if board |
a.nav-item.right(href=`/${board ? board._id+'/' : 'global'}manage.html`) Manage |
||||||
a.nav-item.right(href=`/login?redirect=/${board._id}/index`) Login |
a.nav-item.right(href='/login.html') Login |
||||||
a.nav-item.right(href=`/${board._id}/manage`) Manage |
|
||||||
else |
|
||||||
a.nav-item.right(href='/login') Login |
|
||||||
|
@ -1,15 +1,15 @@ |
|||||||
| Page: |
| Page: |
||||||
span |
if page === 1 |
||||||
a(href=`/${board._id}/index`) [#{1}] |
a(href=`/${board._id}/index.html`) [#{1}] |
||||||
| |
| |
||||||
- for(let i = 2; i <= pages; i++) |
else |
||||||
|
a(href=`/${board._id}/index.html`) #{1} |
||||||
|
| |
||||||
|
- for(let i = 2; i <= maxPage; i++) |
||||||
if i === page |
if i === page |
||||||
span |
a(href=`/${board._id}/${i}.html`) [#{i}] |
||||||
a(href=`/${board._id}/${i}`) [#{i}] |
| |
||||||
| |
|
||||||
|
|
||||||
else |
else |
||||||
span |
a(href=`/${board._id}/${i}.html`) #{i} |
||||||
a(href=`/${board._id}/${i}`) #{i} |
| |
||||||
| |
|
||||||
| | |
| | |
||||||
|
@ -1,45 +1,47 @@ |
|||||||
section.form-wrapper.flex-center.mv-10 |
section.form-wrapper.flex-center |
||||||
form.form-post(action=`/forms/board/${board._id}/post`, enctype='multipart/form-data', method='POST') |
details.toggle-label |
||||||
//input(type='hidden' name='_csrf' value=csrf) |
summary Show Post Form |
||||||
input(type='hidden' name='thread' value=thread != null ? thread.postId : null) |
form.form-post(action=`/forms/board/${board._id}/post`, enctype='multipart/form-data', method='POST') |
||||||
unless board.settings.forceAnon |
//input(type='hidden' name='_csrf' value=csrf) |
||||||
section.postform-row |
input(type='hidden' name='thread' value=thread != null ? thread.postId : null) |
||||||
.postform-label Name |
unless board.settings.forceAnon |
||||||
input#name(type='text', name='name', placeholder=board.defaultName autocomplete='off' maxlength='50') |
section.postform-row |
||||||
section.postform-row |
.postform-label Name |
||||||
.postform-label Subject |
input#name(type='text', name='name', placeholder=board.defaultName autocomplete='off' maxlength='50') |
||||||
input#title(type='text', name='subject', autocomplete='off' maxlength='50') |
|
||||||
section.postform-row |
|
||||||
.postform-label Email |
|
||||||
input#name(type='text', name='email', autocomplete='off' maxlength='50') |
|
||||||
else |
|
||||||
section.postform-row |
|
||||||
.postform-label Sage |
|
||||||
label.postform-style.ph-5 |
|
||||||
input#spoiler(type='checkbox', name='email', value='sage') |
|
||||||
| Sage |
|
||||||
if !thread |
|
||||||
section.postform-row |
section.postform-row |
||||||
.postform-label Subject |
.postform-label Subject |
||||||
input#title(type='text', name='subject', autocomplete='off' maxlength='50') |
input#title(type='text', name='subject', autocomplete='off' maxlength='50') |
||||||
section.postform-row |
section.postform-row |
||||||
.postform-label Message |
.postform-label Email |
||||||
textarea#message(name='message', rows='5', autocomplete='off' maxlength='2000') |
input#name(type='text', name='email', autocomplete='off' maxlength='50') |
||||||
section.postform-row |
else |
||||||
.postform-label Files |
section.postform-row |
||||||
input#file(type='file', name='file' multiple='multiple') |
.postform-label Sage |
||||||
label.postform-style.ph-5.ml-1 |
label.postform-style.ph-5 |
||||||
input#spoiler(type='checkbox', name='spoiler', value='true') |
input#spoiler(type='checkbox', name='email', value='sage') |
||||||
| Spoiler |
| Sage |
||||||
section.postform-row |
if !thread |
||||||
.postform-label Password |
section.postform-row |
||||||
input#password(type='password', name='password', autocomplete='off' placeholder='password for deleting post later' maxlength='50') |
.postform-label Subject |
||||||
section.postform-row |
input#title(type='text', name='subject', autocomplete='off' maxlength='50') |
||||||
.postform-label Captcha |
section.postform-row |
||||||
.postform-col |
.postform-label Message |
||||||
img.captcha(src='/captcha' width=200 height=80) |
textarea#message(name='message', rows='5', autocomplete='off' maxlength='2000') |
||||||
input#captcha(type='text', name='captcha', autocomplete='off' placeholder='captcha text' maxlength='6') |
if board.settings.maxFiles !== 0 |
||||||
if !thread |
section.postform-row |
||||||
input(type='submit', value='New Thread') |
.postform-label Files |
||||||
else |
input#file(type='file', name='file' multiple='multiple') |
||||||
input(type='submit', value='Reply') |
label.postform-style.ph-5.ml-1 |
||||||
|
input#spoiler(type='checkbox', name='spoiler', value='true') |
||||||
|
| Spoiler |
||||||
|
section.postform-row |
||||||
|
.postform-label Password |
||||||
|
input#password(type='password', name='password', autocomplete='off' placeholder='password for deleting post later' maxlength='50') |
||||||
|
if board.settings.captcha |
||||||
|
section.postform-row |
||||||
|
.postform-label Captcha |
||||||
|
.postform-col |
||||||
|
img.captcha(src='/captcha' width=200 height=80) |
||||||
|
input#captcha(type='text', name='captcha', autocomplete='off' placeholder='captcha text' maxlength='6') |
||||||
|
input(type='submit', value=`New ${threads ? 'Thread' : 'Reply'}`) |
||||||
|
//.mode Posting mode: #{threads ? 'Thread' : 'Reply'} |
||||||
|
@ -1,23 +1,30 @@ |
|||||||
mixin catalogtile(board, post, truncate) |
mixin catalogtile(board, post, truncate) |
||||||
article(class='catalog-tile') |
article(class='catalog-tile') |
||||||
- const postURL = `/${board._id}/thread/${post.postId}#${post.postId}` |
- const postURL = `/${board._id}/thread/${post.postId}.html#${post.postId}` |
||||||
a.catalog-tile-button(href=postURL) Open Thread |
a.catalog-tile-button(href=postURL) Open Thread |
||||||
if post.subject |
if post.subject |
||||||
span: a.no-decoration.post-subject(href=postURL) #{post.subject} |
span: a.no-decoration.post-subject(href=postURL) #{post.subject} |
||||||
.catalog-tile-content |
.catalog-tile-content |
||||||
if post.files.length > 0 |
if post.files.length > 0 |
||||||
.post-file-src |
.post-file-src |
||||||
a(href=`/${board._id}/thread/${post.postId}#${post.postId}`) |
a(href=postURL) |
||||||
if post.spoiler |
if post.spoiler |
||||||
object(data='/img/spoiler.png' width='64' height='64') |
object(data='/img/spoiler.png' width='64' height='64') |
||||||
else |
else |
||||||
object.catalog-thumb(data=`/img/thumb-${post.files[0].filename.split('.')[0]}.jpg` width='64' height='64') |
object.catalog-thumb(data=`/img/thumb-${post.files[0].filename.split('.')[0]}.jpg` width='64' height='64') |
||||||
header.post-info |
header.post-info |
||||||
span: a(href=postURL) ##{post.postId} |
if post.sticky |
||||||
|
img(src='/img/sticky.svg' height='12') |
||||||
|
if post.saged |
||||||
|
img(src='/img/saged.svg' height='12') |
||||||
|
if post.locked |
||||||
|
img(src='/img/locked.svg' height='12') |
||||||
|
| |
||||||
|
span: a(href=postURL) No.#{post.postId} |
||||||
| |
| |
||||||
span Replies: #{post.replyposts} |
span Replies: #{post.replyposts} |
||||||
| |
| |
||||||
span Images: #{post.replyfiles} |
span Images: #{post.replyfiles} |
||||||
br |
|
||||||
if post.message |
if post.message |
||||||
|
br |
||||||
blockquote.no-m-p.post-message !{post.message} |
blockquote.no-m-p.post-message !{post.message} |
||||||
|
Loading…
Reference in new issue