add pfps, some polish

This commit is contained in:
biglyderv 2024-11-25 14:12:44 -05:00
parent 351b9f2bc8
commit 85b3e55e3d
16 changed files with 142 additions and 230 deletions

3
.gitignore vendored
View file

@ -2,4 +2,5 @@
/db /db
/package-lock.json /package-lock.json
/uploads /uploads
/videos /videos
/pfp

18
client/settings.js Normal file
View file

@ -0,0 +1,18 @@
import Route from "../route.js";
import auth from "../form/auth.js";
// TODO: rewrite
let main = new Route([auth], async function (req, res, input) {
let { username } = input;
return res.render('form', {
data: [
{ label: "Description", type: "textarea", name: "desc" },
{ label: "Avatar", type: "file", name: "file" }
],
'route': '/api/upload/settings',
'title': 'User Settings',
username
}); /* todo: form in not a file */
});
export default main;

View file

@ -18,12 +18,17 @@ let main = new Route([comment], async function (req, res, input) {
req.query.id req.query.id
]); ]);
let user = await db.all('SELECT * FROM user WHERE username = ?', [
req.query.id
]);
return res.render('user', { return res.render('user', {
...input, ...input,
id, id,
videos, videos,
followers, followers,
following following,
user
}); });
}); });

2
db.js
View file

@ -19,6 +19,8 @@ async function initDb() {
await db.run('CREATE TABLE IF NOT EXISTS follow (username TEXT, target TEXT);'); await db.run('CREATE TABLE IF NOT EXISTS follow (username TEXT, target TEXT);');
await db.run(`CREATE TABLE IF NOT EXISTS user (username TEXT, bio TEXT);`);
return db; return db;
} }

34
form/settings.js Normal file
View file

@ -0,0 +1,34 @@
import Route from "../route.js";
import initDb from "../db.js";
import auth from "../form/auth.js";
import {exec} from 'node:child_process';
import { promisify } from "node:util";
const execP = promisify(exec);
let db = await initDb();
// TODO: rewrite
let main = new Route([auth], async function (req, res, input) {
let { path } = req.file;
let { username } = input;
let { desc } = req.body;
if (username == '!nobody' || !desc || !req.file) return { 'success': false, 'message': 'Some fields are missing' };
await execP(`magick ${path} pfp/${username}.png`);
await db.run('DELETE FROM user WHERE username = ?', [
username,
]);
await db.run('INSERT INTO user (username,bio) VALUES (?,?)', [
username,
desc
]);
res.send({ 'success': true, 'message': 'Metadata updated', redir: `/user?id=${username}` });
});
export default main;

View file

@ -12,6 +12,7 @@ const upload = multer({ dest: 'uploads/' });
app.use(cookieParser()); app.use(cookieParser());
app.use('/static', express.static('static')); app.use('/static', express.static('static'));
app.use('/videos', express.static('videos')); app.use('/videos', express.static('videos'));
app.use('/pfp', express.static('pfp'));
app.engine('.ejs', ejs.__express); app.engine('.ejs', ejs.__express);
app.set('views', './views'); app.set('views', './views');
app.set('view engine', 'ejs'); app.set('view engine', 'ejs');

View file

@ -4,12 +4,14 @@ import register from "./client/register.js";
import upload from "./client/upload.js"; import upload from "./client/upload.js";
import player from "./client/player.js"; import player from "./client/player.js";
import user from "./client/user.js"; import user from "./client/user.js";
import settings from "./client/settings.js";
import loginB from "./form/login.js"; import loginB from "./form/login.js";
import registerB from "./form/register.js"; import registerB from "./form/register.js";
import uploadB from "./form/upload.js"; import uploadB from "./form/upload.js";
import auth from "./form/auth.js";
import commentB from "./form/comment.js"; import commentB from "./form/comment.js";
import settingsB from "./form/settings.js";
import auth from "./form/auth.js";
import follow from './form/follow.js'; import follow from './form/follow.js';
const routes = { const routes = {
@ -24,17 +26,21 @@ routes.client = {
register, register,
upload, upload,
video: player, video: player,
user user,
settings
} }
routes.get = { routes.get = {
}; };
routes.form = { routes.form = {
login: loginB, login: loginB,
register: registerB, register: registerB,
upload: uploadB, upload: uploadB,
auth, auth,
comment: commentB, comment: commentB,
follow follow,
settings: settingsB
}; };
async function iterate(req, res, index) { async function iterate(req, res, index) {

View file

@ -1,46 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="256"
height="256"
viewBox="0 0 256 256"
version="1.1"
id="svg1"
inkscape:version="1.3.2 (091e20ef0f, 2023-11-25, custom)"
sodipodi:docname="channel.svg"
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="1.4142136"
inkscape:cx="122.32947"
inkscape:cy="96.166522"
inkscape:window-width="1860"
inkscape:window-height="1004"
inkscape:window-x="30"
inkscape:window-y="46"
inkscape:window-maximized="1"
inkscape:current-layer="layer1" />
<defs
id="defs1" />
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<path
id="path21"
style="color:#000000;fill:#ffffff;stroke-linecap:round;stroke-linejoin:round;-inkscape-stroke:none;paint-order:stroke fill markers"
d="M 105.20508 14.765625 A 12.5 12.5 0 0 0 90.914062 25.171875 L 83.042969 75.189453 L 39.90625 75.189453 A 12.5 12.5 0 0 0 27.40625 87.689453 A 12.5 12.5 0 0 0 39.90625 100.18945 L 79.109375 100.18945 L 70.357422 155.81055 L 39.90625 155.81055 A 12.5 12.5 0 0 0 27.40625 168.31055 A 12.5 12.5 0 0 0 39.90625 180.81055 L 66.423828 180.81055 L 59.164062 226.94336 A 12.5 12.5 0 0 0 69.570312 241.23438 A 12.5 12.5 0 0 0 83.861328 230.82812 L 91.730469 180.81055 L 139.18555 180.81055 L 131.92578 226.94336 A 12.5 12.5 0 0 0 142.33203 241.23438 A 12.5 12.5 0 0 0 156.62305 230.82812 L 164.49219 180.81055 L 216.09375 180.81055 A 12.5 12.5 0 0 0 228.59375 168.31055 A 12.5 12.5 0 0 0 216.09375 155.81055 L 168.42773 155.81055 L 177.17773 100.18945 L 216.09375 100.18945 A 12.5 12.5 0 0 0 228.59375 87.689453 A 12.5 12.5 0 0 0 216.09375 75.189453 L 181.11133 75.189453 L 188.37109 29.056641 A 12.5 12.5 0 0 0 177.9668 14.765625 A 12.5 12.5 0 0 0 163.67578 25.171875 L 155.80469 75.189453 L 108.34961 75.189453 L 115.60938 29.056641 A 12.5 12.5 0 0 0 105.20508 14.765625 z M 104.41602 100.18945 L 151.87109 100.18945 L 143.11914 155.81055 L 95.666016 155.81055 L 104.41602 100.18945 z " />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.5 KiB

View file

@ -1,47 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="256"
height="256"
viewBox="0 0 256 256"
version="1.1"
id="svg1"
inkscape:version="1.3.2 (091e20ef0f, 2023-11-25, custom)"
sodipodi:docname="chat.svg"
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="1.4142136"
inkscape:cx="122.32947"
inkscape:cy="96.166522"
inkscape:window-width="1860"
inkscape:window-height="1004"
inkscape:window-x="30"
inkscape:window-y="46"
inkscape:window-maximized="1"
inkscape:current-layer="layer1" />
<defs
id="defs1" />
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<path
id="rect5"
style="fill:#ffffff;stroke:#ffffff;stroke-width:5;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;paint-order:stroke fill markers"
d="m 75.453401,45.088826 c -32.320369,0 -58.33923,26.061849 -58.33923,58.435624 0,32.37377 26.018861,58.43562 58.33923,58.43562 h 26.272709 c -2.62751,23.22026 -18.803725,39.27367 -47.03315,48.9513 48.88863,-4.55457 71.98574,-28.43749 99.57855,-48.9513 h 26.27269 c 32.32037,0 58.34163,-26.06185 58.34163,-58.43562 0,-32.373775 -26.02126,-58.435624 -58.34163,-58.435624 z M 54.375589,78.436904 c 13.832827,-5.15e-4 25.046675,11.23186 25.046161,25.087546 5.14e-4,13.85567 -11.213335,25.08805 -25.046161,25.08754 -13.831893,-8.1e-4 -25.04429,-11.2328 -25.043777,-25.08754 -5.14e-4,-13.854749 11.211882,-25.086742 25.043777,-25.087546 z m 73.305851,0 c 13.83282,-5.15e-4 25.04667,11.23186 25.04617,25.087546 5e-4,13.85567 -11.21335,25.08805 -25.04617,25.08754 -13.8319,-8.1e-4 -25.04429,-11.2328 -25.04378,-25.08754 -5.1e-4,-13.854749 11.21188,-25.086743 25.04378,-25.087546 z m 73.30585,0 c 13.83281,-5.15e-4 25.04667,11.23186 25.04616,25.087546 5.1e-4,13.85567 -11.21335,25.08805 -25.04616,25.08754 -13.8319,-8.1e-4 -25.0443,-11.2328 -25.04379,-25.08754 -5.1e-4,-13.854749 11.21189,-25.086743 25.04379,-25.087546 z"
sodipodi:nodetypes="ssscccssssccccccccccccccc" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.5 KiB

View file

@ -1,50 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="256"
height="256"
viewBox="0 0 256 256"
version="1.1"
id="svg1"
inkscape:version="1.3.2 (091e20ef0f, 2023-11-25, custom)"
sodipodi:docname="extra.svg"
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="1.4142136"
inkscape:cx="122.68302"
inkscape:cy="96.16652"
inkscape:window-width="1860"
inkscape:window-height="1004"
inkscape:window-x="30"
inkscape:window-y="46"
inkscape:window-maximized="1"
inkscape:current-layer="layer1" />
<defs
id="defs1" />
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<path
id="path7"
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:4.99999;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
d="M 127.98047 9.2089844 A 77.378253 77.378253 0 0 0 50.597656 86.589844 A 77.378253 77.378253 0 0 0 127.98047 163.9668 A 77.378253 77.378253 0 0 0 198.08594 118.64453 C 196.25399 119.46262 194.27647 119.94281 192.26562 119.97461 C 184.74478 120.36642 177.57152 114.36239 176.45703 106.94727 C 176.10249 98.548701 176.26522 90.137067 176.22852 81.732422 L 163.18164 81.732422 C 158.85576 81.553758 154.47904 82.145329 150.19531 81.3125 C 143.32593 80.00577 138.04382 73.379759 137.98242 66.439453 C 137.65472 58.954936 143.63387 51.843523 151.01562 50.734375 C 159.41375 50.384219 167.82436 50.541182 176.22852 50.507812 L 176.22852 47.916016 C 176.30386 40.684641 176.10075 33.44977 176.35547 26.220703 A 77.378253 77.378253 0 0 0 127.98047 9.2089844 z M 127.98047 181.50977 A 161.06057 225.06591 0 0 0 14.613281 246.79102 L 241.38672 246.79102 A 161.06057 225.06591 0 0 0 127.98047 181.50977 z " />
<path
id="path5"
style="color:#000000;fill:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;-inkscape-stroke:none;paint-order:stroke fill markers"
d="m 191.84044,18.097959 a 9.757645,9.757645 0 0 0 -9.75765,9.757645 v 28.507569 h -28.50757 a 9.757645,9.757645 0 0 0 -9.75764,9.757645 9.757645,9.757645 0 0 0 9.75764,9.757645 h 28.50757 v 28.507567 a 9.757645,9.757645 0 0 0 9.75765,9.75765 9.757645,9.757645 0 0 0 9.75764,-9.75765 V 75.878463 h 28.50757 a 9.757645,9.757645 0 0 0 9.75765,-9.757645 9.757645,9.757645 0 0 0 -9.75765,-9.757645 H 201.59808 V 27.855604 a 9.757645,9.757645 0 0 0 -9.75764,-9.757645 z" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.9 KiB

View file

@ -1,46 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="256"
height="256"
viewBox="0 0 256 256"
version="1.1"
id="svg1"
inkscape:version="1.3.2 (091e20ef0f, 2023-11-25, custom)"
sodipodi:docname="login.svg"
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="1.4142136"
inkscape:cx="122.32947"
inkscape:cy="95.812966"
inkscape:window-width="1860"
inkscape:window-height="1005"
inkscape:window-x="30"
inkscape:window-y="45"
inkscape:window-maximized="1"
inkscape:current-layer="layer1" />
<defs
id="defs1" />
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<path
id="path7"
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:4.99999;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
d="M 127.98078,9.208089 A 77.378253,77.378253 0 0 0 50.59861,86.590271 77.378253,77.378253 0 0 0 127.98078,163.96761 77.378253,77.378253 0 0 0 205.35812,86.590271 77.378253,77.378253 0 0 0 127.98078,9.208089 Z m 0,172.302221 a 161.06057,225.06591 0 0 0 -113.36661,65.2816 h 226.77166 a 161.06057,225.06591 0 0 0 -113.40505,-65.2816 z" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.7 KiB

View file

@ -89,7 +89,7 @@ form {
} }
.form-entry { .form-entry, textarea {
display: block; display: block;
} }
@ -168,10 +168,6 @@ form {
color: var(--dark-1); color: var(--dark-1);
} }
textarea {
display: block;
}
.progressbar { .progressbar {
background-color: var(--light-1); background-color: var(--light-1);
border: solid var(--dark-2) 2px; border: solid var(--dark-2) 2px;
@ -216,4 +212,14 @@ img.dark {
pre { pre {
white-space: pre-wrap; white-space: pre-wrap;
overflow-x: auto; overflow-x: auto;
}
.pfp-wrapper {
display: flex;
}
.avatar {
width: 50px;
height: 50px;
margin-right: 15px;
} }

View file

@ -1,6 +1,5 @@
<form enctype='multipart/form-data' method='POST' action='/api/form/comment'> <form enctype='multipart/form-data' method='POST' action='/api/form/comment'>
<h1>Comments</h1> <h1>Comments</h1>
<!-- probably component-ify this -->
<div class='form-message'></div> <div class='form-message'></div>
<input name='targetId' hidden value='<%= id %>'> <input name='targetId' hidden value='<%= id %>'>
<input name='targetType' hidden value='<%= route %>'> <input name='targetType' hidden value='<%= route %>'>
@ -9,13 +8,20 @@
<% for (let comment of comments) { %> <% for (let comment of comments) { %>
<div class='comment'> <div class='comment'>
<div><b> <div class='pfp-wrapper'>
<a href='/client/user?id=<%= comment.username %>'><%= comment.username %></a> <img src='/pfp/<%= comment.username %>.png' class='avatar'>
</b></div> <div>
<div><b> <div><b>
<%= (new Date(comment.date)+'').split(/(GMT|UTC)/g)[0] %> <a href='/client/user?id=<%= comment.username %>'>
</b></div> <%= comment.username %>
<pre><%= comment.content %></pre> </a>
</b></div>
<div><b>
<%= (new Date(comment.date)+'').split(/(GMT|UTC)/g)[0] %>
</b></div>
<pre><%= comment.content %></pre>
</div>
</div>
</div> </div>
<% } %> <% } %>
</form> </form>

View file

@ -10,5 +10,8 @@
<a href="/client/upload"> <a href="/client/upload">
Upload Upload
</a> </a>
<a href="/client/settings">
Settings
</a>
<% } %> <% } %>
</div> </div>

View file

@ -15,12 +15,17 @@
<%= videoData.title %> <%= videoData.title %>
</b> </b>
</div> </div>
<div>Created by <b><a href="/client/user?id=<%= videoData.username %>">
@<%= videoData.username %></a></b> <div class='pfp-wrapper'>
</a> on <img src='/pfp/<%= videoData.username %>.png' class='avatar'>
<b> <div>
<%= (new Date(videoData.date)+'').split(/(GMT|UTC)/g)[0] %> Created by <b><a href="/client/user?id=<%= videoData.username %>">
</b> @<%= videoData.username %></a></b>
</a> on
<b>
<%= (new Date(videoData.date)+'').split(/(GMT|UTC)/g)[0] %>
</b>
</div>
</div> </div>
<pre><%= videoData.desc %></pre> <pre><%= videoData.desc %></pre>
</div> </div>

View file

@ -3,24 +3,38 @@
<h1>User</h1> <h1>User</h1>
<div class='form-message'></div> <div class='form-message'></div>
<div class='user'> <div class='user'>
<p> <div class='pfp-wrapper'>
<b>@<%= id %></b> <img src='/pfp/<%= id %>.png' class='avatar'>
</p> <div>
<details> <p>
<summary> <%= following.length %> following</summary> <b>@<%= id %></b>
<% for (let user of following) { %> </p>
<a href='/client/user?id=<%= user.target %>'><%= user.target %></a> <details>
<%} %> <summary>
</details> <%= following.length %> following
<details> </summary>
<summary> <%= followers.length %> followers</summary> <% for (let user of following) { %>
<% for (let user of followers) { %> <a href='/client/user?id=<%= user.target %>'>
<a href='/client/user?id=<%= user.username %>'><%= user.username %></a> <%= user.target %>
<%} %> </a>
</details> <%} %>
<input name='target' hidden value="<%= id %>"> </details>
<input type='submit' value="Follow"> <details>
<summary>
<%= followers.length %> followers
</summary>
<% for (let user of followers) { %>
<a href='/client/user?id=<%= user.username %>'>
<%= user.username %>
</a>
<%} %>
</details>
<input name='target' hidden value="<%= id %>">
<input type='submit' value="Follow">
</div>
</div>
</div> </div>
<pre><%= user[0].bio %></pre>
</form> </form>
<div class='area'> <div class='area'>
<h1>Uploaded Videos</h1> <h1>Uploaded Videos</h1>