Better rendering for messages

This commit is contained in:
Akif9748 2022-08-11 17:55:48 +03:00
parent faeb832fdd
commit e7dafd3561
8 changed files with 183 additions and 156 deletions

View file

@ -32,6 +32,7 @@ And, you can learn about API in `util/APIDOCS.md`.
| Admin | 🟢 | HIGH |
| Message count | 🟢 | MEDIUM |
| Delete user | 🟢 | HIGH |
| Undelete | 🔴 | MEDIUM |
| About me | 🔴 | LOW |
| Edit user | 🔴 | HIGH |
| IP ban | 🔴 | MEDIUM |
@ -42,6 +43,7 @@ And, you can learn about API in `util/APIDOCS.md`.
| Ratelimit | 🟢 | HIGH |
| Send | 🟢 | HIGH |
| Delete | 🟢 | HIGH |
| Undelete | 🔴 | MEDIUM |
| React | 🟢 | MEDIUM |
| Edit | 🔴 | MEDIUM |
@ -51,12 +53,14 @@ And, you can learn about API in `util/APIDOCS.md`.
| Ratelimit | 🟢 | HIGH |
| Create | 🟢 | HIGH |
| Delete | 🟢 | HIGH |
| Undelete | 🔴 | MEDIUM |
| Edit | 🔴 | MEDIUM |
### API
| To do | Is done? | Priority |
| ----- | -------- | -------- |
| Other clients for forum via API | 🟢 | LOW |
| Get message**s** | 🔴 | MEDIUM |
| Send message | 🟢 | MEDIUM |
| Create thread | 🟢 | MEDIUM |
| Get info about thread | 🟢 | MEDIUM |

View file

@ -99,7 +99,8 @@ hr {
border-color: var(--col-8);
}
button, input {
button,
input {
font-family: monospace;
background-color: var(--col-bg);
border: 2px solid var(--col-8);
@ -186,11 +187,11 @@ button:hover {
}
/*
*****************************
IMAGES
*****************************
*/
div.message {
border: 2px solid var(--col-8);
padding: 10px;
}
/*

View file

@ -1,34 +1,71 @@
import request from "./request.js";
document.addEventListener("click", async e => {
if (e.target.id === "delete_thread") {
const response = await request("/api/threads/"+e.target.value+"/delete");
if (response.result.deleted) {
alert("Thread deleted");
window.location.href = "/threads";
const messages = document.getElementById("messages");
function renderMessage(message) {
const messageElement = document.createElement("div");
messageElement.classList.add("message");
messageElement.setAttribute("id", "message-" + message.id);
messageElement.innerHTML = `
<h3 style="float:right;">${new Date(message.time).toLocaleString()}</h3>
<h2>
<img class="circle" src=${message.author.avatar} alt=${message.author.name}>
<a href=${"/users/" + message.author.id}> ${message.author.name}</a>:
</h2>
<h2>${message.content}</h2><br>
<div id="message-delete-${message.id}">
${!message.deleted ?
`<form style="display:inline;">
<button id="delete_message" value="${message.id}" type="submit">DELETE</button>
</form>` :
"<h3 style=\"display:inline;\">This message has been deleted</h3>"}
</div>
<div style="float: right;">
<h3 id="count${message.id}" style="display:inline;">${message.reactCount}</h3>
<button style="display:inline;" id="like" value="${message.id}">+🔼</button>
<button style="display:inline;" id="dislike" value="${message.id}" >-🔽</button>
</div>
`;
messages.appendChild(messageElement);
messages.innerHTML += "<br>";
};
/**
* Main Renderer
*/
(async () => {
const { result } = await fetch(`/api/threads/${messages.getAttribute("value")}/messages/`).then(res => res.json());
if (result?.error) {
document.getElementById("messages").innerHTML
+= '<div class="message"><h1>THIS THREAD HAS NOT GOT ANY MESSAGE</h1></div>';
} else
for (const message of result) {
const arr = Object.values(message.react || {})
message.reactCount = arr.filter(Boolean).length - arr.filter(x => !x).length;
renderMessage(message);
}
} else if (e.target.id === "delete_message") {
const response = await request(`/api/messages/${e.target.value}/delete`);
if (response.result.deleted) {
alert("Message deleted");
location.reload();
}
} /*else if (e.target.id === "edit_thread") {
window.location.href = "/threads/<%= thread.id %>/edit";
} */
})();
if (!e.target.id.includes("like")) return;
const res = await request("/api/messages/" + e.target.value + "/react/" + e.target.id)
document.getElementById("count" + e.target.value).innerHTML = res.result;
});
document.getElementById("send").addEventListener("submit", async e => {
/**
* Message Sender
*/
document.getElementById("send").addEventListener("submit", async e => {
e.preventDefault();
const form = e.target;
@ -37,28 +74,38 @@ document.getElementById("send").addEventListener("submit", async e => {
.then(res => {
if (!res) return;
form.reset();
const message = res.result;
document.getElementById("messages").innerHTML += `<br>
<div id="message-${message.id}" style="border: 2px solid #444444; padding: 10px;">
<h3 style="float:right;">${new Date(message.time).toLocaleString()}</h3>
<h2>
<img class="circle" src=${message.author.avatar} alt=${message.author.name}>
<a href="/users/${message.author.id}"> ${message.author.name}</a>:
</h2>
<h2>${message.content}</h2><br>
<form style="display:inline;" action="/message/${message.id}/delete/" method="post">
</a><button type="submit">DELETE</button>
</form>
<div style="float: right;">
<h3 id="count${message.id}" style="display:inline;">0</h3>
<button style="display:inline;" id="like" value="${message.id}">+🔼</button>
<button style="display:inline;" id="dislike" value="${message.id}" >-🔽</button>
</div>
</div>`;
res.result.reactCount = 0;
renderMessage(res.result);
});
});
/**
* Button Listener
*/
document.addEventListener("click", async e => {
// e.preventDefault();
if (e.target.id === "delete_thread") {
const response = await request("/api/threads/" + e.target.value + "/delete");
if (response.result.deleted) {
alert("Thread deleted");
window.location.href = "/threads";
}
} else if (e.target.id === "delete_message") {
e.preventDefault();
const response = await request(`/api/messages/${e.target.value}/delete`);
if (response.result.deleted) {
alert("Message deleted");
document.getElementById("message-delete-" + e.target.value).innerHTML="<h3 style=\"display:inline;\">This message has been deleted</h3>";
}
} /*else if (e.target.id === "edit_thread") {
window.location.href = "/threads/<%= thread.id }/edit";
} */
if (!e.target.id.includes("like")) return;
const res = await request("/api/messages/" + e.target.value + "/react/" + e.target.id)
document.getElementById("count" + e.target.value).innerHTML = res.result;
});

View file

@ -1,10 +1,11 @@
const { UserModel, MessageModel, ThreadModel } = require("../../../models");
const { MessageModel, ThreadModel } = require("../../../models");
const rateLimit = require('express-rate-limit')
const { Router } = require("express")
const app = Router();
app.get("/:id", async (req, res) => {

View file

@ -5,18 +5,36 @@ const app = Router();
app.get("/:id", async (req, res) => {
const { id = null } = req.params;
if (!id) return res.error(400, "Missing id in query")
const { id } = req.params;
const thread = await ThreadModel.get(id);
if (thread && (req.user?.admin || !thread.deleted))
res.complate( thread);
res.complate(thread);
else
return res.error(404, "We have not got any thread declared as this id.");
return res.error(404, "We don't have any thread with this id.");
});
app.get("/:id/messages/", async (req, res) => {
const { id = null } = req.params;
const limit = Number(req.query.limit);
const query = { threadID: id };
if (!req.user.admin) query.deleted = false;
const options = { sort: { date: -1 } };
if (limit) options.limit = limit;
const messages = await MessageModel.find(query, null, options)
if (!messages.length) return res.error(404, "We don't have any messages in this thread.");
res.complate(messages);
})
app.post("/", async (req, res) => {
@ -36,10 +54,10 @@ app.post("/", async (req, res) => {
app.post("/:id/delete", async (req, res) => {
const thread = await ThreadModel.get(req.params.id);
if (!thread || thread.deleted) return res.error( 404, "We have not got any thread declared as this id.");
if (!thread || thread.deleted) return res.error(404, "We don't have any thread with this id.");
const user = req.user;
if (user.id != thread.authorID && !user.admin)
return res.error( 403, "You have not got permission for this.");
return res.error(403, "You have not got permission for this.");
thread.deleted = true;
await thread.save();

View file

@ -22,6 +22,7 @@ You need this headers for send request to API:
- POST `/api/users/:id/admin` for give admin permissions for a user.
- GET `/api/threads/:id` for fetch thread.
- GET `/api/threads/:id/messages/:limit` for fetch messages in thread.
- POST `/api/threads` for create thread.
- POST `/api/threads/:id/delete` for delete thread.

View file

@ -3,102 +3,56 @@
<%- include("extra/header", { title: thread.title }) %>
<body>
<body>
<%- include("extra/navbar", {user}) %>
<%- include("extra/navbar", {user}) %>
<h1 style="font-size: 35px;">
<%= thread.title %>
</h1>
<h1 style="font-size: 35px;">
<%= thread.title %>
</h1>
<h2 style="display:inline;">By <a href=<%="/users/" + thread.author.id %>> <%= thread.author.name %></a>
<img class="circle" src=<%= thread.author.avatar %> alt=<%= thread.author.name %>>
</h2>
<h2 style="display:inline;">By <a href=<%="/users/" + thread.author.id %>> <%= thread.author.name %></a>
<img class="circle" src=<%=thread.author.avatar %> alt=<%= thread.author.name %>>
</h2>
<% if (user && !thread.deleted){ %>
<% if (user && !thread.deleted){ %>
<button id="delete_thread" value="<%= thread.id %>" style="display:inline;" type="submit">DELETE</button>
<button id="edit_thread" style="display:inline;" type="submit">EDIT</button>
<% } else { %>
<h3 style="display:inline;">This thread has been deleted</h3>
<% }; %>
<hr>
<div id="messages">
<% messages.forEach(message=>{ %>
<% if (message){ %>
<div id="message-<%= message.id %>" style="border: 2px solid #444444; padding: 10px;">
<h3 style="float:right;">
<%=new Date(message.time).toLocaleString() %>
</h3>
<h2>
<img class="circle" src=<%=message.author.avatar %> alt=<%= message.author.name %>>
<a href=<%="/users/" + message.author.id %>> <%= message.author.name %></a>:
</h2>
<h2>
<%= message.content %>
</h2>
<br>
<% if (user){ %>
<% if (!message.deleted){ %>
<form style="display:inline;">
<button id="delete_message" value="<%= message.id %>" type="submit">DELETE</button>
</form>
<% } else { %>
<h3 style="display:inline;">This message has been deleted</h3>
<button id="delete_thread" value="<%= thread.id %>" style="display:inline;" type="submit">DELETE</button>
<button id="edit_thread" style="display:inline;" type="submit">EDIT</button>
<% } else if (thread.deleted) { %>
<h3 style="display:inline;">This thread has been deleted</h3>
<% }; %>
<div style="float: right;">
<h3 id="count<%= message.id %>" style="display:inline;"><%= message.reactCount %></h3>
<button style="display:inline;" id="like" value="<%= message.id %>">+🔼</button>
<button style="display:inline;" id="dislike" value="<%= message.id %>" >-🔽</button>
</div>
<hr>
<% } %>
<div id="messages" value="<%= thread.id %>">
<% if (!user){ %>
<h1>Guests cant view messages!</h1>
<% }%>
</div>
<hr>
</div>
<form id="send">
<textarea rows="4" cols="133" name="content"></textarea>
<input name="threadID" type="hidden" value="<%= thread.id %>"></input>
<% } else { %>
<div id="deleted-message" style="border: 2px solid #444444; padding: 10px;">
<h1>DELETED MESSAGE</h1>
</div>
<% } %>
<br>
<br>
<% if (user){ %>
<button type="submit">Send!</button>
<%} else {%>
<button disabled>Login for send</button>
<% }%>
<% }); %>
</form>
<% if (user){ %>
<script type="module" src="/js/thread.js"></script>
<% }%>
</div>
<hr>
<form id= "send">
<textarea rows="4" cols="133" name="content"></textarea>
<input name="threadID" type="hidden" value="<%= thread.id %>"></input>
<br>
<% if (user){ %>
<button type="submit">Send!</button>
<%} else {%>
<button disabled>Login for send</button>
<% }%>
</form>
<% if (user){ %>
<script type="module" src="/js/thread.js"></script>
<% }%>
<%- include("extra/footer") %>
</body>
<%- include("extra/footer") %>
</body>
</html>

View file

@ -61,7 +61,8 @@
const response = await request("/api/users/<%= member.id %>/admin");
if (response.result.admin)
return alert("Making admin of "+response.result.name+" is success!");
return alert("Making admin of " + response.result.name + " is success!");
}
const response = await request("/api/users/<%= member.id %>/delete");
@ -74,11 +75,11 @@
</script>
<% }; %>
<% if (member.deleted) {%>
<h1>This user has been deleted!</h1>
<% }; %>
<% if (member.deleted) {%>
<h1>This user has been deleted!</h1>
<% }; %>
<%- include("extra/footer") %>
<%- include("extra/footer") %>
</body>
</html>