Added markdown to editors

This commit is contained in:
Akif9748 2022-09-17 21:36:33 +03:00
parent 38042faaf5
commit 3010efc00a
10 changed files with 66 additions and 26 deletions

View file

@ -46,9 +46,9 @@ Akf-forum has got an API for AJAX (fetch), other clients etc. And, you can learn
| mod role, permissions | ⚪ | | mod role, permissions | ⚪ |
| upload other photos, model for it | ⚪ | | upload other photos, model for it | ⚪ |
| categories page is need a update, thread count in category | ⚪ | | categories page is need a update, thread count in category | ⚪ |
| preview for send messages in markdown format | | | preview for send messages in markdown format | 💚 |
| DC auth will store code for taking tokens, and create secret model setting | ⚪ | | DC auth will store code for taking tokens, and create secret model setting | ⚪ |
- max lengths for html :/
## Major Version History ## Major Version History
- V4: Caching - V4: Caching
- V3: New Theme - V3: New Theme

View file

@ -21,3 +21,9 @@ form {
margin-bottom: 10px; margin-bottom: 10px;
border: 2px solid var(--borders); border: 2px solid var(--borders);
} }
.CodeMirror{
width: 422.5px;
}

View file

@ -1,5 +1,6 @@
import request from "./request.js"; import request from "./request.js";
let editing;
// THREAD: // THREAD:
window.edit_thread = async function (id) { window.edit_thread = async function (id) {
@ -28,7 +29,7 @@ window.undelete_thread = async function (id) {
// MESSAGES: // MESSAGES:
window.send_edit = async function (id) { window.send_edit = async function (id) {
const message = document.getElementById(`message-${id}`); const message = document.getElementById(`message-${id}`);
const content = message.querySelector("#content").value; const content = editing.value();
const res = await request(`/api/messages/${id}/`, "PATCH", { content }); const res = await request(`/api/messages/${id}/`, "PATCH", { content });
if (res.error) return; if (res.error) return;
@ -36,12 +37,21 @@ window.send_edit = async function (id) {
message.querySelector(".content").innerHTML = converter.makeHtml(res.content); message.querySelector(".content").innerHTML = converter.makeHtml(res.content);
} }
window.edit_message = async function (id) { window.edit_message = async function (id) {
const content = document.getElementById(`message-${id}`).querySelector(".content"); const message = document.getElementById(`message-${id}`)
const content = message.querySelector(".content");
content.innerHTML = ` content.innerHTML = `
<textarea rows="4" cols="40" id="content">${content.rawText}</textarea> <textarea rows="4" cols="40" id="content"></textarea>
<button onclick="send_edit(${id});" class="btn-primary">Edit!</button>`; <button onclick="send_edit(${id});" class="btn-primary">Edit!</button>`;
const cnt = message.querySelector("#content");
editing = new SimpleMDE({
element: cnt,
spellChecker: false,
height: "200px",
previewRender: t => converter.makeHtml(t)
});
editing.value(content.rawText)
} }
window.undelete_message = async function (id) { window.undelete_message = async function (id) {
const response = await request(`/api/messages/${id}/undelete`); const response = await request(`/api/messages/${id}/undelete`);

View file

@ -16,7 +16,7 @@ app.get("/:id", async (req, res) => {
const query = { categoryID: category.id }; const query = { categoryID: category.id };
if (!req.user?.admin) query.deleted= false; if (!req.user?.admin) query.deleted= false;
let threads = await ThreadModel.find(query).limit(10).skip(page * 10); let threads = await ThreadModel.find(query).limit(10).skip(page * 10).sort({ time: -1 });
threads = await Promise.all(threads.map(thread => thread.get_author())); threads = await Promise.all(threads.map(thread => thread.get_author()));
res.reply("threads", { threads, page, title: `Threads in ${category.name}`, desp: category.desp, pages: Math.ceil(await ThreadModel.count(query) / 10) }); res.reply("threads", { threads, page, title: `Threads in ${category.name}`, desp: category.desp, pages: Math.ceil(await ThreadModel.count(query) / 10) });

View file

@ -5,7 +5,7 @@ const { ThreadModel, MessageModel, CategoryModel } = require("../models")
app.get("/", async (req, res) => { app.get("/", async (req, res) => {
const page = Number(req.query.page) || 0; const page = Number(req.query.page) || 0;
const query = req.user?.admin ? {} : { deleted: false }; const query = req.user?.admin ? {} : { deleted: false };
let threads = await ThreadModel.find(query).limit(10).skip(page * 10); let threads = await ThreadModel.find(query).limit(10).skip(page * 10).sort({ time: -1 });
threads = await Promise.all(threads.map(thread => thread.get_author())); threads = await Promise.all(threads.map(thread => thread.get_author()));
return res.reply("threads", { threads, page, title: "Threads", desp: threads.length + " threads are listed", pages: Math.ceil(await ThreadModel.count(query) / 10) }); return res.reply("threads", { threads, page, title: "Threads", desp: threads.length + " threads are listed", pages: Math.ceil(await ThreadModel.count(query) / 10) });

View file

@ -3,17 +3,17 @@
<%- include("extra/meta", {title: "Create thread!" }) %> <%- include("extra/meta", {title: "Create thread!" }) %>
<body style="text-align: center;"> <body >
<link rel="stylesheet" href="/css/create_thread.css" /> <link rel="stylesheet" href="/css/create_thread.css" />
<link rel="stylesheet" href="https://cdn.jsdelivr.net/simplemde/latest/simplemde.min.css">
<script src="https://cdn.jsdelivr.net/simplemde/latest/simplemde.min.js"></script>
<%- include("extra/navbar") %> <%- include("extra/navbar") %>
<form> <form>
<h2 class="title" style="align-self: baseline;">Title:</h2> <h2 class="title" style="align-self: baseline;">Title:</h2>
<input name="title" class="input" required></input> <input name="title" class="input" required></input>
<h2 class="title" style="align-self: baseline;">Content:</h2> <h2 class="title" style="align-self: baseline;">Content:</h2>
<textarea rows="4" cols="50" name="content" class="input" required></textarea> <textarea rows="4" cols="50" name="content" id="textarea" class="input" ></textarea>
<h2 class="title" style="align-self: baseline;">Category:</h2> <h2 class="title" style="align-self: baseline;">Category:</h2>
<select name="category"> <select name="category">
@ -27,6 +27,18 @@
<script type="module"> <script type="module">
const textarea = document.getElementById("textarea");
const simplemde = new SimpleMDE({
autosave: {
enabled: true,
uniqueId: "thread-create",
delay: 1000,
},
element: textarea,
spellChecker: false
});
import request from "../../js/request.js"; import request from "../../js/request.js";
document.addEventListener("submit", async e => { document.addEventListener("submit", async e => {
@ -36,7 +48,7 @@
const response = await request("/api/threads/", "POST", { const response = await request("/api/threads/", "POST", {
title: data.get("title"), title: data.get("title"),
content: data.get("content"), content: simplemde.value(),
category: data.get("category") category: data.get("category")
}); });

View file

@ -7,8 +7,9 @@
<link rel="stylesheet" href="/css/login.css" /> <link rel="stylesheet" href="/css/login.css" />
<%- include("extra/navbar") %> <%- include("extra/navbar") %>
<% if(discord) { %>
<a href="<%=discord%>" class="btn-outline-primary">Login with discord</a> <a href="<%=discord%>" class="btn-outline-primary">Login with discord</a>
<% } %>
<h1 class="title">Login</h1> <h1 class="title">Login</h1>
<form action="/login?redirect=<%= redirect !== "/register" ? redirect : "/" %>" method="post"> <form action="/login?redirect=<%= redirect !== "/register" ? redirect : "/" %>" method="post">

View file

@ -8,8 +8,9 @@
<link rel="stylesheet" href="/css/login.css" /> <link rel="stylesheet" href="/css/login.css" />
<%- include("extra/navbar") %> <%- include("extra/navbar") %>
<% if(discord) { %>
<a href="<%=discord%>" class="btn-outline-primary">Login with discord</a> <a href="<%=discord%>" class="btn-outline-primary">Login with discord</a>
<% } %>
<h1 class="title">Register</h1> <h1 class="title">Register</h1>

View file

@ -7,6 +7,8 @@
<body> <body>
<%- include("extra/navbar") %> <%- include("extra/navbar") %>
<script src="https://cdnjs.cloudflare.com/ajax/libs/showdown/2.1.0/showdown.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/showdown/2.1.0/showdown.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/simplemde/latest/simplemde.min.css">
<script src="https://cdn.jsdelivr.net/simplemde/latest/simplemde.min.js"></script>
<link href='https://unpkg.com/boxicons@2.1.2/css/boxicons.min.css' rel='stylesheet'> <link href='https://unpkg.com/boxicons@2.1.2/css/boxicons.min.css' rel='stylesheet'>
@ -108,34 +110,42 @@
<script type="module" src="/js/thread.js"></script> <script type="module" src="/js/thread.js"></script>
<div class="message" id="send-div"> <div class="message" id="send-div">
<form id="send" style="width:100%"> <form id="send" style="width:100%">
<textarea rows="4" name="content" required></textarea> <textarea rows="4" id="textarea"></textarea>
<input name="threadID" type="hidden" value="<%= thread.id %>"></input>
<input name="page" type="hidden" value="<%= page %>"></input> <input name="page" type="hidden" value="<%= page %>"></input>
<button class="btn-primary">Send!</button> <button class="btn-primary">Send!</button>
</form> </form>
</div> </div>
<script type="module"> <script type="module">
const textarea = document.getElementById("textarea");
const simplemde = new SimpleMDE({
autosave: {
enabled: true,
uniqueId: "thread-<%= thread.id %>",
delay: 1000,
},
element: textarea,
spellChecker: false,
previewRender: t=> converter.makeHtml(t)
});
import request from "../../js/request.js"; import request from "../../js/request.js";
document.getElementById("send").addEventListener("submit", async e => { document.getElementById("send").addEventListener("submit", async e => {
e.preventDefault(); e.preventDefault();
const data = new FormData(e.target);
const res = await request("/api/messages", "POST", { const res = await request("/api/messages", "POST", {
threadID: "<%= thread.id %>", threadID: "<%= thread.id %>",
content: data.get("content") content: simplemde.value()
}) })
simplemde.clearAutosavedValue();
let tp = Number("<%= thread.pages %>") let tp = Number("<%= thread.pages %>")
let tm = Number("<%= thread.count %>") let tm = Number("<%= thread.count %>")
if (tp * 10 === tm) tp++; if (tp * 10 === tm) tp++;
if (res) location.href = `/threads/<%= thread.id %>?page=${tp-1}`; if (res) location.href = `/threads/<%= thread.id %>?page=${tp-1}`;
}); });
</script> </script>
<% }%> <% }%>

View file

@ -13,7 +13,7 @@
<div class="content"> <div class="content">
<% if (!member.discordID && user?.id === member.id) { %> <% if (!member.discordID && discord && user?.id === member.id) { %>
<a href="<%=discord%>" class="btn-outline-primary">Login with discord</a> <a href="<%=discord%>" class="btn-outline-primary">Login with discord</a>
<% } %> <% } %>
<% if (user?.admin || user?.id === member.id) { %> <% if (user?.admin || user?.id === member.id) { %>