diff --git a/README.md b/README.md
index b259af2..5c106b9 100644
--- a/README.md
+++ b/README.md
@@ -33,11 +33,13 @@ Akf-forum has got an API for AJAX, other clients etc. And, you can learn about A
- Profile photos will store in database
- regex for pfp for now and
- admin perm for undelete, thread + message
-- page support for threads
+- page support for threads, send, if multi page, send => other page
- message ""
- author name of thread
- page for threads - users
-- edit & delete button for thread
+- API, ?fast=
+- fix error messages, ~~declared as id~~, other...
+
### Frontend
### User
| To do | Is done? | Priority |
diff --git a/models/Message.js b/models/Message.js
index 2808503..5cdeff9 100644
--- a/models/Message.js
+++ b/models/Message.js
@@ -14,7 +14,8 @@ const schema = new mongoose.Schema({
react: {
like: [Number],
dislike: [Number]
- }
+ },
+ index: { type: Number, default: 0 }
})
diff --git a/models/Secret.js b/models/Secret.js
index b4bb922..e8c71e0 100644
--- a/models/Secret.js
+++ b/models/Secret.js
@@ -1,12 +1,9 @@
-const { Schema, model } = require("mongoose")
-
-const schema = new Schema({
+const mongoose = require("mongoose")
+const schema = new mongoose.Schema({
username: { type: String, unique: true },
password: String,
- id: { type:String, unique: true }
-
-
+ id: { type: String, unique: true }
});
-module.exports = model('secret', schema);
\ No newline at end of file
+module.exports = mongoose.model('secret', schema);
\ No newline at end of file
diff --git a/public/js/thread.js b/public/js/thread.js
index 0f14e00..1e6b885 100644
--- a/public/js/thread.js
+++ b/public/js/thread.js
@@ -1,46 +1,4 @@
import request from "./request.js";
-const message_div = document.getElementById("messages");
-
-
-function render_message(message) {
- const messageElement = document.createElement("div");
- messageElement.classList.add("message");
- messageElement.setAttribute("id", "message-" + message.id);
-
- messageElement.innerHTML = `
-
- ${new Date(message.time).toLocaleString()}
-
-
-
-
${message.content.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll("\"", """).replaceAll("'", "'").replaceAll("\n", "
")}
-
- ${/* if */!message.deleted ?
- `
-
DELETE
-
EDIT
- ` /* else */ :
- `
This message has been deleted
-
UNDELETE
- `
-
- }
-
-
-`;
-
- message_div.appendChild(messageElement);
- message_div.innerHTML += "
";
-};
-
-window.scrollTo(0, document.body.scrollHeight);
/**
* Message Sender
@@ -52,10 +10,7 @@ document.getElementById("send")?.addEventListener("submit", async e => {
const data = new FormData(form);
request("/api/messages", "POST", { threadID: data.get("threadID"), content: data.get("content") })
.then(res => {
- if (!res) return;
- form.reset();
- res.reactCount = 0;
- render_message(res);
+ if (res) location.href = `/messages/${res.id}`;
});
});
@@ -63,7 +18,7 @@ document.getElementById("send")?.addEventListener("submit", async e => {
* OTHER FUNCTIONS
*/
-async function delete_thread(id) {
+window.delete_thread = async function (id) {
const response = await request("/api/threads/" + id + "/delete");
if (response.deleted) {
alert("Thread deleted");
@@ -71,37 +26,39 @@ async function delete_thread(id) {
}
}
-async function undelete_thread(id) {
+window.undelete_thread = async function (id) {
const response = await request("/api/threads/" + id + "/undelete");
if (!response.deleted) {
alert("Thread undeleted");
location.reload();
-
}
}
-async function undelete_message(id) {
+window.undelete_message = async function (id) {
const response = await request(`/api/messages/${id}/undelete`);
- if (!response.deleted)
- document.getElementById("message-delete-" + id).innerHTML = `DELETE`;
+ if (response.deleted) return;
+ document.getElementById("deleted-" + id).remove();
+ document.getElementById("dot-" + id).innerHTML = `
+ DELETE
+ EDIT
+ `
+
}
-async function delete_message(id) {
+window.delete_message = async function (id) {
const response = await request(`/api/messages/${id}/delete`);
if (response.deleted) {
alert("Message deleted");
- document.getElementById("message-delete-" + id).innerHTML = `
- This message has been deleted
+ document.getElementById("dots-" + id).innerHTML = `
+
+ `+ document.getElementById("dots-" + id).innerHTML;
+
+ document.getElementById("dot-" + id).innerHTML = `
UNDELETE`;// ADMIN PERM FIX
}
}
-async function react(id, type) {
+window.react = async function (id, type) {
const res = await request(`/api/messages/${id}/react/${type}`)
- document.getElementById(`count${id}`).innerHTML = res.reactCount;
+ document.getElementById(`like-${id}`).innerHTML = res.react.like.length;
+ document.getElementById(`dislike-${id}`).innerHTML = res.react.dislike.length;
}
-
-window.delete_message = delete_message;
-window.undelete_message = undelete_message;
-window.react = react;
-window.delete_thread = delete_thread;
-window.undelete_thread = undelete_thread;
\ No newline at end of file
diff --git a/routes/admin.js b/routes/admin.js
index d662bef..fec6ead 100644
--- a/routes/admin.js
+++ b/routes/admin.js
@@ -3,15 +3,7 @@ const { Router } = require("express")
const app = Router();
app.get("/", async (req, res) => {
- if (!req.session.userid) return res.redirect('/login');
-
- const user = req.user;
-
- if (!user?.admin) return res.error( 403, "You have not got permissions for view to this page.");
-
- res.reply("admin", { user2: false })
+ if (!req.user?.admin) return res.error(403, "You have not got permissions for view to this page.");
+ res.reply("admin")
});
-
-
-
-module.exports = app;
+module.exports = app;
\ No newline at end of file
diff --git a/routes/api/routes/messages.js b/routes/api/routes/messages.js
index 6c194c0..fc80d0c 100644
--- a/routes/api/routes/messages.js
+++ b/routes/api/routes/messages.js
@@ -31,7 +31,7 @@ app.post("/", rateLimit({
if (!thread) return res.error(404, `We don't have any thread with id ${threadID}.`);
- const message = await new MessageModel({ content, author: req.user, threadID: thread.id }).takeId();
+ const message = await new MessageModel({ content, author: req.user, threadID: thread.id, index: thread.messages.length }).takeId();
await message.save();
await thread.push(message.id).save();
diff --git a/routes/api/routes/threads.js b/routes/api/routes/threads.js
index 9d9ab0b..a2c6df9 100644
--- a/routes/api/routes/threads.js
+++ b/routes/api/routes/threads.js
@@ -26,7 +26,7 @@ app.get("/:id/messages/", async (req, res) => {
const query = { threadID: id };
if (!req.user.admin) query.deleted = false;
- const options = { sort: { date: -1 } };
+ const options = { sort: { time: -1 } };
if (limit) options.limit = limit;
if (skip) options.skip = skip;
diff --git a/routes/login.js b/routes/login.js
index abb073e..12d9c03 100644
--- a/routes/login.js
+++ b/routes/login.js
@@ -3,7 +3,7 @@ const { Router } = require("express");
const app = Router();
const bcrypt = require("bcrypt");
-app.get("/", (req, res) => res.reply("login",{redirect: req.query.redirect,user:null}));
+app.get("/", (req, res) => res.reply("login", { redirect: req.query.redirect, user: null }));
app.post("/", async (req, res) => {
req.session.userid = null;
@@ -14,19 +14,19 @@ app.post("/", async (req, res) => {
const user = await SecretModel.findOne({ username });
if (user) {
- if (!await bcrypt.compare(password, user.password)) return res.error( 403, 'Incorrect Password!')
+ if (!await bcrypt.compare(password, user.password)) return res.error(403, 'Incorrect Password!')
const member = await UserModel.findOne({ name: username });
- if (!member || member.deleted) return res.error( 403, 'Incorrect Username and/or Password!')
+ if (!member || member.deleted) return res.error(403, 'Incorrect Username and/or Password!')
req.session.userid = user.id;
- res.redirect( req.query.redirect || '/');
+ res.redirect(req.query.redirect || '/');
} else
- res.error( 403, 'Incorrect Username and/or Password!')
+ res.error(403, 'Incorrect Username and/or Password!')
} else
- res.error( 400, "You forgot entering some values")
+ res.error(400, "You forgot entering some values")
diff --git a/routes/messages.js b/routes/messages.js
index 917ed5f..26fdc2e 100644
--- a/routes/messages.js
+++ b/routes/messages.js
@@ -7,8 +7,9 @@ const app = Router();
app.get("/:id", async (req, res) => {
const message = await MessageModel.get(req.params.id);
- if (!message || (message.deleted && req.user && !req.user.admin)) return res.error( 404, "We have not got any message declared as this id.");
- res.redirect("/threads/" + message.threadID+"?scroll="+req.params.id);
+ if (!message || (message.deleted && req.user && !req.user.admin)) return res.error( 404,
+ `We don't have any message with id ${req.params.id}.`);
+ res.redirect(`/threads/${message.threadID}?scroll=${req.params.id}`);
});
diff --git a/routes/threads.js b/routes/threads.js
index 6d01ae3..e539a0d 100644
--- a/routes/threads.js
+++ b/routes/threads.js
@@ -1,7 +1,7 @@
const { Router } = require("express");
const app = Router();
-const { ThreadModel,MessageModel } = require("../models")
+const { ThreadModel, MessageModel } = require("../models")
app.get("/", async (req, res) => {
@@ -14,27 +14,33 @@ app.get("/", async (req, res) => {
app.get("/create*", (req, res) => res.reply("create_thread"));
-app.get("/:id", async (req, res) => {
+app.get("/:id/", async (req, res) => {
- const { id } = req.params;
- const page = req.query.page || 0;
- const thread = await ThreadModel.get(id).skip(page * 10).limit(page * 10 + 10);
- thread.views++;
+ const { user, params: { id } } = req
- if (thread && (req.user?.admin || !thread.deleted)) {
- const messages = await Promise.all(thread.messages.map(async id => {
- const message = await MessageModel.get(id)
- message.content = message.content.replaceAll("&", "&")
- .replaceAll("<", "<").replaceAll(">", ">")
- .replaceAll("\"", """).replaceAll("'", "'")
- .replaceAll("\n", "
");
- return req.user?.admin || !message?.deleted ? message.toObject({ virtuals: true }) : null;
- }));
+ const page = Number(req.query.page || 0);
+ const thread = await ThreadModel.get(id)
+ if (thread && (user?.admin || !thread.deleted)) {
+ thread.views++;
+ const query = { threadID: id };
+ if (!user || !user.admin) query.deleted = false;
+
+ const messages = await MessageModel.find(query).sort({ time: 1 }).skip(page * 10).limit(page * 10 + 10)
+ .then(messages => messages.map(message => {
+ message.content = message.content.replaceAll("&", "&")
+ .replaceAll("<", "<").replaceAll(">", ">")
+ .replaceAll("\"", """).replaceAll("'", "'")
+ .replaceAll("\n", "
");
+ return message.toObject({ virtuals: true });
+ }))
+
+
+ res.reply("thread", { page, thread, messages, scroll: req.query.scroll || thread.messages[0].id });
+
+ thread.save();
- res.reply("thread", { page,thread, messages, scroll: req.query.scroll || thread.messages[0]});
} else
res.error(404, "We have not got this thread.");
- thread.save();
});
diff --git a/routes/users.js b/routes/users.js
index 2bcda13..76400f1 100644
--- a/routes/users.js
+++ b/routes/users.js
@@ -11,17 +11,16 @@ app.get("/", async ({ user }, res) => {
app.get("/:id", async (req, res) => {
const user = req.user
- const { id = null } = req.params;
+ const { id } = req.params;
const member = await UserModel.get(id);
-
if (member && (user?.admin || !member.deleted)) {
- const message = await MessageModel.count({ "author.id": id });// this place was having problem. fixed
+ const message = await MessageModel.count({ "author.id": id });
const thread = await ThreadModel.count({ "author.id": id });
res.reply("user", { member, counts: { message, thread } })
}
- else res.error(404, "We have not got this user.");
+ else res.error(404, `We don't have any user with id ${id}.`);
});
diff --git a/views/extra/ot.ejs b/views/extra/ot.ejs
index 7c59c47..e69de29 100644
--- a/views/extra/ot.ejs
+++ b/views/extra/ot.ejs
@@ -1,97 +0,0 @@
-
-
-
-<%- include("extra/meta", {title: "Thread list!" }) %>
-
-
-
- <%- include("extra/navbar") %>
-
-
- <% if (user){ %>
-
- <% }%>
-
-
- <%= thread.title %>
- View count: <%= thread.views %>
-
-
-
- <% if (user && !thread.deleted){ %>
-
- DELETE
- EDIT
- <% } else if (thread.deleted) { %>
- This thread has been deleted
- UNDELETE
-
- <% }; %>
-
-
-
-
-
-
-
- <% messages.filter(Boolean).forEach(message=>{ %>
-
-
-
-
<%= new Date(message.time).toLocaleString() %>
-
-
-
-
<%= message.content%>
-
-
- <% if (!message.deleted){ %>
-
-
DELETE
-
EDIT
- <% }else{ %>
-
This message has been deleted
-
UNDELETE
- <% } %>
-
-
-
-
- <% }); %>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/views/thread.ejs b/views/thread.ejs
index 7c4bb62..aaa5f8d 100644
--- a/views/thread.ejs
+++ b/views/thread.ejs
@@ -12,65 +12,96 @@
<% if (user){ %>
<% }; %>
+
<%= thread.title %>
<%= new Date(thread.time).toLocaleString() %> • Views: <%= thread.views %>
+
+
+
+
+ <% if (user && !thread.deleted){ %>
+
+
DELETE
+
EDIT
+ <% } else if (thread.deleted) { %>
+
This thread has been deleted
+
UNDELETE
+
+ <% }; %>
+
+
- <% messages.filter(Boolean).forEach(message=>{ %>
+ <% messages.filter(Boolean).forEach(message=>{ %>
-
-
-
-
-
- <%= new Date(message.time).toLocaleDateString() %>
+
+
+
+
+
+ <%= new Date(message.time).toLocaleDateString() %>
+
+
+ <%= new Date(message.time).toLocaleTimeString() %>
+
+
+
+
<%- message.content %>
+ <% if(user){ %>
+ <% if(user.id === message.author.id || user.admin){ %>
+
+
+ <% if (message.deleted){ %>
+
+ <% } %>
+
-
- <%= new Date(message.time).toLocaleTimeString() %>
-
-
-
<%- message.content %>
-<% if(user){ %>
- <% if(user.id === message.author.id || user.admin){ %>
-
-
-
-
-
- <% if (!message.deleted){ %>
-
<% }else if (user.admin){ %>
-
- <% } %>
-
- <% } %>
+
Undelete
+ <% } %>
+
+ <% } %>
-
-
- <%=message.react.like.length %>
-
-
- <%=message.react.dislike.length %>
-
-
- <% }; %>
+
+
+
+
<%=message.react.like.length %>
+
+
+
+
<%=message.react.dislike.length %>
+
+
+ <% }; %>
-
+
<% }); %>
+
+
+