add messages
This commit is contained in:
parent
c029d47157
commit
175975ceeb
11 changed files with 220 additions and 10 deletions
25
client/messages.js
Normal file
25
client/messages.js
Normal file
|
@ -0,0 +1,25 @@
|
|||
import Route from "../route.js";
|
||||
import auth from "../form/auth.js";
|
||||
import initDb from "../db.js";
|
||||
|
||||
let db = await initDb();
|
||||
|
||||
let main = new Route([auth], async function (req, res, input) {
|
||||
let { username } = input;
|
||||
|
||||
let msgs = await db.all('SELECT * FROM message WHERE username = ? ORDER BY date DESC', [
|
||||
username
|
||||
]);
|
||||
|
||||
await db.run('UPDATE message SET read = ? WHERE username = ?', [
|
||||
'true',
|
||||
username
|
||||
]);
|
||||
|
||||
return res.render('messages', {
|
||||
...input,
|
||||
msgs
|
||||
});
|
||||
});
|
||||
|
||||
export default main;
|
2
db.js
2
db.js
|
@ -22,6 +22,8 @@ async function initDb() {
|
|||
await db.run(`CREATE TABLE IF NOT EXISTS user (username TEXT, bio TEXT);`);
|
||||
await db.run(`CREATE TABLE IF NOT EXISTS captcha (key TEXT, solution TEXT);`);
|
||||
|
||||
await db.run(`CREATE TABLE IF NOT EXISTS message (username TEXT, targetType TEXT, targetId TEXT, date REAL, content TEXT, read TEXT);`);
|
||||
|
||||
return db;
|
||||
}
|
||||
|
||||
|
|
14
form/auth.js
14
form/auth.js
|
@ -21,13 +21,25 @@ let main = new Route([], async function (req, res, input) {
|
|||
username
|
||||
]);
|
||||
|
||||
let isRead = false;
|
||||
|
||||
if (username) {
|
||||
let msgs = await db.all('SELECT * FROM message WHERE username = ? AND read = ?', [
|
||||
username,
|
||||
'false'
|
||||
]);
|
||||
|
||||
isRead = msgs.length > 0
|
||||
}
|
||||
|
||||
return {
|
||||
username,
|
||||
valid: valid[0] ? valid[0].valid : 'noexist',
|
||||
url: `${process.env.URL}/client/${route}?id=${id || ''}`,
|
||||
icon: `${process.env.URL}/static/img/logo.png`,
|
||||
rootUrl: process.env.URL,
|
||||
ogType: 'website'
|
||||
ogType: 'website',
|
||||
isRead: isRead ? 'unread' : 'read'
|
||||
};
|
||||
});
|
||||
|
||||
|
|
|
@ -23,7 +23,20 @@ let main = new Route([auth], async function (req, res, input) {
|
|||
id
|
||||
]);
|
||||
|
||||
res.send({ 'message': 'Comment sent', redirect: `/client/${targetType}?id=${targetId}` });
|
||||
let u = `/client/${targetType}?id=${targetId}`;
|
||||
|
||||
if (targetType == 'user') {
|
||||
await db.run('INSERT INTO message (username, targetType, targetId, date, content, read) VALUES (?,?,?,?,?,?)', [
|
||||
targetId,
|
||||
'profile comment',
|
||||
u,
|
||||
+new Date(),
|
||||
content,
|
||||
'false'
|
||||
]);
|
||||
}
|
||||
|
||||
res.send({ 'message': 'Comment sent', redirect: u });
|
||||
});
|
||||
|
||||
export default main;
|
|
@ -8,6 +8,7 @@ import settings from "./client/settings.js";
|
|||
import e404 from "./client/e404.js";
|
||||
import tou from "./client/tou.js";
|
||||
import captcha from './client/captcha.js';
|
||||
import messages from './client/messages.js';
|
||||
|
||||
import loginB from "./form/login.js";
|
||||
import registerB from "./form/register.js";
|
||||
|
@ -35,7 +36,8 @@ routes.client = {
|
|||
settings,
|
||||
e404,
|
||||
tou,
|
||||
captcha
|
||||
captcha,
|
||||
messages
|
||||
}
|
||||
|
||||
routes.get = {
|
||||
|
|
59
static/img/read.svg
Normal file
59
static/img/read.svg
Normal file
|
@ -0,0 +1,59 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="217.18312"
|
||||
height="217.18312"
|
||||
viewBox="0 0 217.18312 217.18313"
|
||||
version="1.1"
|
||||
id="svg1"
|
||||
inkscape:version="1.4 (e7c3feb100, 2024-10-09)"
|
||||
sodipodi:docname="read.svg"
|
||||
inkscape:export-filename="logo.png"
|
||||
inkscape:export-xdpi="452.63"
|
||||
inkscape:export-ydpi="452.63"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<sodipodi:namedview
|
||||
id="namedview1"
|
||||
pagecolor="#000000"
|
||||
bordercolor="#ffffff"
|
||||
borderopacity="0.24705882"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:zoom="2"
|
||||
inkscape:cx="112.5"
|
||||
inkscape:cy="86.25"
|
||||
inkscape:window-width="1918"
|
||||
inkscape:window-height="1056"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="22"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false" />
|
||||
<defs
|
||||
id="defs1" />
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(47.661312,-32.274754)">
|
||||
<rect
|
||||
style="fill:#e64e4e;fill-opacity:1;stroke:#ffffff;stroke-width:15;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect6"
|
||||
width="202.18312"
|
||||
height="202.18312"
|
||||
x="-40.161308"
|
||||
y="39.774757" />
|
||||
<path
|
||||
style="fill:#ef8f8f;fill-opacity:1;stroke:#ffffff;stroke-width:25;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
|
||||
d="M -32.66127,47.774754 61.186505,133.77475 157.83862,44.274754 Z"
|
||||
id="path2"
|
||||
sodipodi:nodetypes="cccc" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2 KiB |
65
static/img/unread.svg
Normal file
65
static/img/unread.svg
Normal file
|
@ -0,0 +1,65 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="217.18312"
|
||||
height="217.18312"
|
||||
viewBox="0 0 217.18312 217.18313"
|
||||
version="1.1"
|
||||
id="svg1"
|
||||
inkscape:version="1.4 (e7c3feb100, 2024-10-09)"
|
||||
sodipodi:docname="unread.svg"
|
||||
inkscape:export-filename="logo.png"
|
||||
inkscape:export-xdpi="452.63"
|
||||
inkscape:export-ydpi="452.63"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<sodipodi:namedview
|
||||
id="namedview1"
|
||||
pagecolor="#000000"
|
||||
bordercolor="#ffffff"
|
||||
borderopacity="0.24705882"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:zoom="2"
|
||||
inkscape:cx="112.5"
|
||||
inkscape:cy="86.75"
|
||||
inkscape:window-width="1290"
|
||||
inkscape:window-height="1056"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="22"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false" />
|
||||
<defs
|
||||
id="defs1" />
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(47.661312,-32.274754)">
|
||||
<rect
|
||||
style="fill:#e64e4e;fill-opacity:1;stroke:#ffffff;stroke-width:15;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect6"
|
||||
width="202.18312"
|
||||
height="202.18312"
|
||||
x="-40.161308"
|
||||
y="39.774757" />
|
||||
<path
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:25;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
|
||||
d="m 41.430323,72.560616 h 38.99996 L 57.9053,159.62856 Z"
|
||||
id="path1" />
|
||||
<ellipse
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:25;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
|
||||
id="path2"
|
||||
cx="58.301094"
|
||||
cy="198.05249"
|
||||
rx="10.735944"
|
||||
ry="11.119534" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.2 KiB |
|
@ -72,20 +72,29 @@ body {
|
|||
|
||||
.header-link,
|
||||
.link {
|
||||
text-decoration: none;
|
||||
font-weight: 700;
|
||||
color: var(--white)
|
||||
}
|
||||
|
||||
.header-link {
|
||||
|
||||
text-decoration: none;
|
||||
padding-left: .5em;
|
||||
margin-left: .5em;
|
||||
border-left: solid var(--white) 2px
|
||||
border-left: solid var(--white) 2px;
|
||||
}
|
||||
|
||||
.header>a {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 1.5em;
|
||||
}
|
||||
|
||||
.header-img {
|
||||
height: 2em;
|
||||
width: 2em;
|
||||
height: 1.5em;
|
||||
width: 1.5em;
|
||||
object-fit: cover
|
||||
}
|
||||
|
||||
|
|
|
@ -16,7 +16,9 @@ async function formClick(ev) {
|
|||
|
||||
let json = await fetched.json();
|
||||
|
||||
target.querySelector('.captcha').src += '&a=b';
|
||||
let c = target.querySelector('.captcha');
|
||||
|
||||
if (c) c.src += '&a=b';
|
||||
|
||||
target.querySelector('.form-message').textContent = json.message;
|
||||
|
||||
|
|
|
@ -12,5 +12,8 @@
|
|||
<a class="header-link" href="/client/settings">
|
||||
Settings
|
||||
</a>
|
||||
<a class="header-link" href="/client/messages">
|
||||
<img class="header-img" src="/static/img/<%= isRead %>.svg">
|
||||
</a>
|
||||
<% } %>
|
||||
</div>
|
18
views/messages.ejs
Normal file
18
views/messages.ejs
Normal file
|
@ -0,0 +1,18 @@
|
|||
<%- include('header.ejs') -%>
|
||||
<div class="content">
|
||||
<h1>Messages</h1>
|
||||
<% for (let message of msgs) { %>
|
||||
<div class='comment'>
|
||||
<div><b>
|
||||
<%= (new Date(message.date)+'').split(/(GMT|UTC)/g)[0] %>
|
||||
</b></div>
|
||||
<p>A <a class='link' href='<%= message.targetId %>'>
|
||||
<%= message.targetType %>
|
||||
</a> was sent</p>
|
||||
<div class='comment'>
|
||||
<pre><%= message.content %></pre>
|
||||
</div>
|
||||
</div>
|
||||
<% } %>
|
||||
</div>
|
||||
<%- include('footer.ejs') -%>
|
Loading…
Reference in a new issue