mirror of
https://github.com/Akif9748/akf-forum.git
synced 2024-11-26 13:20:41 +03:00
Added markdown to editors
This commit is contained in:
parent
38042faaf5
commit
3010efc00a
10 changed files with 66 additions and 26 deletions
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
}
|
|
@ -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`);
|
||||||
|
|
|
@ -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) });
|
||||||
|
|
|
@ -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) });
|
||||||
|
|
|
@ -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")
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -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">
|
||||||
|
|
|
@ -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>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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>
|
||||||
<% }%>
|
<% }%>
|
||||||
|
|
|
@ -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) { %>
|
||||||
|
|
Loading…
Reference in a new issue