From e7dafd3561d3c0c1d19d4a0c58cf524f0e7b9de2 Mon Sep 17 00:00:00 2001 From: Akif9748 Date: Thu, 11 Aug 2022 17:55:48 +0300 Subject: [PATCH] Better rendering for messages --- README.md | 4 + public/css/styles.css | 15 ++-- public/js/thread.js | 143 ++++++++++++++++++++++------------ routes/api/routes/messages.js | 3 +- routes/api/routes/threads.js | 30 +++++-- util/APIDOCS.md | 1 + views/thread.ejs | 118 +++++++++------------------- views/user.ejs | 25 +++--- 8 files changed, 183 insertions(+), 156 deletions(-) diff --git a/README.md b/README.md index 510aceb..c17d7fa 100644 --- a/README.md +++ b/README.md @@ -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 | diff --git a/public/css/styles.css b/public/css/styles.css index db993d3..3cc5ffb 100644 --- a/public/css/styles.css +++ b/public/css/styles.css @@ -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; +} + /* @@ -257,4 +258,4 @@ img.logo { border: 2px solid var(--col-8); height: 20px; color: var(--col-15); -} +} \ No newline at end of file diff --git a/public/js/thread.js b/public/js/thread.js index e8eb73c..d87f8fa 100644 --- a/public/js/thread.js +++ b/public/js/thread.js @@ -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 = ` + +

${new Date(message.time).toLocaleString()}

+ +

+ ${message.author.name} + ${message.author.name}: +

+ +

${message.content}


+
+ ${!message.deleted ? + `
+ +
` : + "

This message has been deleted

"} +
+
+

${message.reactCount}

+ + +
+`; + + messages.appendChild(messageElement); + messages.innerHTML += "
"; +}; + +/** + * Main Renderer + */ +(async () => { + + const { result } = await fetch(`/api/threads/${messages.getAttribute("value")}/messages/`).then(res => res.json()); + + if (result?.error) { + + document.getElementById("messages").innerHTML + += '

THIS THREAD HAS NOT GOT ANY MESSAGE

'; + + + } 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 += `
-
- -

${new Date(message.time).toLocaleString()}

- -

-${message.author.name} - ${message.author.name}: -

- -

${message.content}


- -
- -
-
-

0

- - -
- -
`; + 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="

This message has been deleted

"; + } + } /*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; + +}); diff --git a/routes/api/routes/messages.js b/routes/api/routes/messages.js index 3be1e7c..86ebba0 100644 --- a/routes/api/routes/messages.js +++ b/routes/api/routes/messages.js @@ -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) => { diff --git a/routes/api/routes/threads.js b/routes/api/routes/threads.js index aabd562..5fb1d3e 100644 --- a/routes/api/routes/threads.js +++ b/routes/api/routes/threads.js @@ -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(); diff --git a/util/APIDOCS.md b/util/APIDOCS.md index 5b4f338..c214318 100644 --- a/util/APIDOCS.md +++ b/util/APIDOCS.md @@ -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. diff --git a/views/thread.ejs b/views/thread.ejs index 84a1422..2c7265e 100644 --- a/views/thread.ejs +++ b/views/thread.ejs @@ -3,102 +3,56 @@ <%- include("extra/header", { title: thread.title }) %> - + - <%- include("extra/navbar", {user}) %> + <%- include("extra/navbar", {user}) %> -

- <%= thread.title %> -

- -

By > <%= thread.author.name %> - alt=<%= thread.author.name %>> -

- - <% if (user && !thread.deleted){ %> +

+ <%= thread.title %> +

- - - <% } else { %> -

This thread has been deleted

- <% }; %> +

By > <%= thread.author.name %> + alt=<%= thread.author.name %>> +

-
-
- <% messages.forEach(message=>{ %> - <% if (message){ %> + <% if (user && !thread.deleted){ %> -
- -

- <%=new Date(message.time).toLocaleString() %> -

- -

- alt=<%= message.author.name %>> - > <%= message.author.name %>: -

- -

- <%= message.content %> -

- -
- - <% if (user){ %> - <% if (!message.deleted){ %> -
- -
- <% } else { %> -

This message has been deleted

+ + + <% } else if (thread.deleted) { %> +

This thread has been deleted

<% }; %> -
-

<%= message.reactCount %>

- - -
- - - <% } %> +
-
+
+ <% if (!user){ %> +

Guests cant view messages!

+ <% }%> +
- <% } else { %> -
-

DELETED MESSAGE

-
- <% } %> -
- - <% }); %> - - -
- -
+
-
- - + + + -
- <% if (user){ %> - - <%} else {%> - - <% }%> +
+ <% if (user){ %> + + <%} else {%> + + <% }%> -
- <% if (user){ %> - - <% }%> + + <% if (user){ %> + + <% }%> - <%- include("extra/footer") %> - + <%- include("extra/footer") %> + - + \ No newline at end of file diff --git a/views/user.ejs b/views/user.ejs index dbfc67c..af2c5e7 100644 --- a/views/user.ejs +++ b/views/user.ejs @@ -59,26 +59,27 @@ if (e.target.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"); - - if (response.result.deleted) + + if (response.result.deleted) alert("User Deleted"); - + }); <% }; %> - <% if (member.deleted) {%> -

This user has been deleted!

- <% }; %> - - <%- include("extra/footer") %> + <% if (member.deleted) {%> +

This user has been deleted!

+ <% }; %> + + <%- include("extra/footer") %> \ No newline at end of file