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

View file

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

View file

@ -1,34 +1,71 @@
import request from "./request.js"; import request from "./request.js";
document.addEventListener("click", async e => {
if (e.target.id === "delete_thread") { const messages = document.getElementById("messages");
const response = await request("/api/threads/"+e.target.value+"/delete");
if (response.result.deleted) { function renderMessage(message) {
alert("Thread deleted"); const messageElement = document.createElement("div");
window.location.href = "/threads"; 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) * Message Sender
*/
document.getElementById("count" + e.target.value).innerHTML = res.result; document.getElementById("send").addEventListener("submit", async e => {
});
document.getElementById("send").addEventListener("submit", async e => {
e.preventDefault(); e.preventDefault();
const form = e.target; const form = e.target;
@ -37,28 +74,38 @@ document.getElementById("send").addEventListener("submit", async e => {
.then(res => { .then(res => {
if (!res) return; if (!res) return;
form.reset(); form.reset();
const message = res.result; res.result.reactCount = 0;
document.getElementById("messages").innerHTML += `<br> renderMessage(res.result);
<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>`;
}); });
}); });
/**
* 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 rateLimit = require('express-rate-limit')
const { Router } = require("express") const { Router } = require("express")
const app = Router(); const app = Router();
app.get("/:id", async (req, res) => { app.get("/:id", async (req, res) => {

View file

@ -5,18 +5,36 @@ const app = Router();
app.get("/:id", async (req, res) => { app.get("/:id", async (req, res) => {
const { id = null } = req.params; const { id } = req.params;
if (!id) return res.error(400, "Missing id in query")
const thread = await ThreadModel.get(id); const thread = await ThreadModel.get(id);
if (thread && (req.user?.admin || !thread.deleted)) if (thread && (req.user?.admin || !thread.deleted))
res.complate( thread); res.complate(thread);
else 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) => { app.post("/", async (req, res) => {
@ -36,10 +54,10 @@ app.post("/", async (req, res) => {
app.post("/:id/delete", async (req, res) => { app.post("/:id/delete", async (req, res) => {
const thread = await ThreadModel.get(req.params.id); 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; const user = req.user;
if (user.id != thread.authorID && !user.admin) 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; thread.deleted = true;
await thread.save(); 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. - POST `/api/users/:id/admin` for give admin permissions for a user.
- GET `/api/threads/:id` for fetch thread. - 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` for create thread.
- POST `/api/threads/:id/delete` for delete thread. - POST `/api/threads/:id/delete` for delete thread.

View file

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

View file

@ -59,26 +59,27 @@
if (e.target.id == "admin") { if (e.target.id == "admin") {
const response = await request("/api/users/<%= member.id %>/admin"); const response = await request("/api/users/<%= member.id %>/admin");
if (response.result.admin)
return alert("Making admin of " + response.result.name + " is success!");
}
if (response.result.admin)
return alert("Making admin of "+response.result.name+" is success!");
}
const response = await request("/api/users/<%= member.id %>/delete"); const response = await request("/api/users/<%= member.id %>/delete");
if (response.result.deleted) if (response.result.deleted)
alert("User Deleted"); alert("User Deleted");
}); });
</script> </script>
<% }; %> <% }; %>
<% if (member.deleted) {%> <% if (member.deleted) {%>
<h1>This user has been deleted!</h1> <h1>This user has been deleted!</h1>
<% }; %> <% }; %>
<%- include("extra/footer") %> <%- include("extra/footer") %>
</body> </body>
</html> </html>