add pfps, some polish
This commit is contained in:
parent
351b9f2bc8
commit
85b3e55e3d
16 changed files with 142 additions and 230 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -2,4 +2,5 @@
|
|||
/db
|
||||
/package-lock.json
|
||||
/uploads
|
||||
/videos
|
||||
/videos
|
||||
/pfp
|
18
client/settings.js
Normal file
18
client/settings.js
Normal 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;
|
|
@ -18,12 +18,17 @@ let main = new Route([comment], async function (req, res, input) {
|
|||
req.query.id
|
||||
]);
|
||||
|
||||
let user = await db.all('SELECT * FROM user WHERE username = ?', [
|
||||
req.query.id
|
||||
]);
|
||||
|
||||
return res.render('user', {
|
||||
...input,
|
||||
id,
|
||||
videos,
|
||||
followers,
|
||||
following
|
||||
following,
|
||||
user
|
||||
});
|
||||
});
|
||||
|
||||
|
|
2
db.js
2
db.js
|
@ -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 user (username TEXT, bio TEXT);`);
|
||||
|
||||
return db;
|
||||
}
|
||||
|
||||
|
|
34
form/settings.js
Normal file
34
form/settings.js
Normal 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;
|
1
index.js
1
index.js
|
@ -12,6 +12,7 @@ const upload = multer({ dest: 'uploads/' });
|
|||
app.use(cookieParser());
|
||||
app.use('/static', express.static('static'));
|
||||
app.use('/videos', express.static('videos'));
|
||||
app.use('/pfp', express.static('pfp'));
|
||||
app.engine('.ejs', ejs.__express);
|
||||
app.set('views', './views');
|
||||
app.set('view engine', 'ejs');
|
||||
|
|
12
routes.js
12
routes.js
|
@ -4,12 +4,14 @@ import register from "./client/register.js";
|
|||
import upload from "./client/upload.js";
|
||||
import player from "./client/player.js";
|
||||
import user from "./client/user.js";
|
||||
import settings from "./client/settings.js";
|
||||
|
||||
import loginB from "./form/login.js";
|
||||
import registerB from "./form/register.js";
|
||||
import uploadB from "./form/upload.js";
|
||||
import auth from "./form/auth.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';
|
||||
|
||||
const routes = {
|
||||
|
@ -24,17 +26,21 @@ routes.client = {
|
|||
register,
|
||||
upload,
|
||||
video: player,
|
||||
user
|
||||
user,
|
||||
settings
|
||||
}
|
||||
|
||||
routes.get = {
|
||||
};
|
||||
|
||||
routes.form = {
|
||||
login: loginB,
|
||||
register: registerB,
|
||||
upload: uploadB,
|
||||
auth,
|
||||
comment: commentB,
|
||||
follow
|
||||
follow,
|
||||
settings: settingsB
|
||||
};
|
||||
|
||||
async function iterate(req, res, index) {
|
||||
|
|
|
@ -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 |
|
@ -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 |
|
@ -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 |
|
@ -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 |
|
@ -89,7 +89,7 @@ form {
|
|||
}
|
||||
|
||||
|
||||
.form-entry {
|
||||
.form-entry, textarea {
|
||||
display: block;
|
||||
}
|
||||
|
||||
|
@ -168,10 +168,6 @@ form {
|
|||
color: var(--dark-1);
|
||||
}
|
||||
|
||||
textarea {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.progressbar {
|
||||
background-color: var(--light-1);
|
||||
border: solid var(--dark-2) 2px;
|
||||
|
@ -216,4 +212,14 @@ img.dark {
|
|||
pre {
|
||||
white-space: pre-wrap;
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.pfp-wrapper {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.avatar {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
margin-right: 15px;
|
||||
}
|
|
@ -1,6 +1,5 @@
|
|||
<form enctype='multipart/form-data' method='POST' action='/api/form/comment'>
|
||||
<h1>Comments</h1>
|
||||
<!-- probably component-ify this -->
|
||||
<div class='form-message'></div>
|
||||
<input name='targetId' hidden value='<%= id %>'>
|
||||
<input name='targetType' hidden value='<%= route %>'>
|
||||
|
@ -9,13 +8,20 @@
|
|||
|
||||
<% for (let comment of comments) { %>
|
||||
<div class='comment'>
|
||||
<div><b>
|
||||
<a href='/client/user?id=<%= comment.username %>'><%= comment.username %></a>
|
||||
</b></div>
|
||||
<div><b>
|
||||
<%= (new Date(comment.date)+'').split(/(GMT|UTC)/g)[0] %>
|
||||
</b></div>
|
||||
<pre><%= comment.content %></pre>
|
||||
<div class='pfp-wrapper'>
|
||||
<img src='/pfp/<%= comment.username %>.png' class='avatar'>
|
||||
<div>
|
||||
<div><b>
|
||||
<a href='/client/user?id=<%= comment.username %>'>
|
||||
<%= comment.username %>
|
||||
</a>
|
||||
</b></div>
|
||||
<div><b>
|
||||
<%= (new Date(comment.date)+'').split(/(GMT|UTC)/g)[0] %>
|
||||
</b></div>
|
||||
<pre><%= comment.content %></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<% } %>
|
||||
</form>
|
|
@ -10,5 +10,8 @@
|
|||
<a href="/client/upload">
|
||||
Upload
|
||||
</a>
|
||||
<a href="/client/settings">
|
||||
Settings
|
||||
</a>
|
||||
<% } %>
|
||||
</div>
|
|
@ -15,12 +15,17 @@
|
|||
<%= videoData.title %>
|
||||
</b>
|
||||
</div>
|
||||
<div>Created by <b><a href="/client/user?id=<%= videoData.username %>">
|
||||
@<%= videoData.username %></a></b>
|
||||
</a> on
|
||||
<b>
|
||||
<%= (new Date(videoData.date)+'').split(/(GMT|UTC)/g)[0] %>
|
||||
</b>
|
||||
|
||||
<div class='pfp-wrapper'>
|
||||
<img src='/pfp/<%= videoData.username %>.png' class='avatar'>
|
||||
<div>
|
||||
Created by <b><a href="/client/user?id=<%= videoData.username %>">
|
||||
@<%= videoData.username %></a></b>
|
||||
</a> on
|
||||
<b>
|
||||
<%= (new Date(videoData.date)+'').split(/(GMT|UTC)/g)[0] %>
|
||||
</b>
|
||||
</div>
|
||||
</div>
|
||||
<pre><%= videoData.desc %></pre>
|
||||
</div>
|
||||
|
|
|
@ -3,24 +3,38 @@
|
|||
<h1>User</h1>
|
||||
<div class='form-message'></div>
|
||||
<div class='user'>
|
||||
<p>
|
||||
<b>@<%= id %></b>
|
||||
</p>
|
||||
<details>
|
||||
<summary> <%= following.length %> following</summary>
|
||||
<% for (let user of following) { %>
|
||||
<a href='/client/user?id=<%= user.target %>'><%= user.target %></a>
|
||||
<%} %>
|
||||
</details>
|
||||
<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 class='pfp-wrapper'>
|
||||
<img src='/pfp/<%= id %>.png' class='avatar'>
|
||||
<div>
|
||||
<p>
|
||||
<b>@<%= id %></b>
|
||||
</p>
|
||||
<details>
|
||||
<summary>
|
||||
<%= following.length %> following
|
||||
</summary>
|
||||
<% for (let user of following) { %>
|
||||
<a href='/client/user?id=<%= user.target %>'>
|
||||
<%= user.target %>
|
||||
</a>
|
||||
<%} %>
|
||||
</details>
|
||||
<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>
|
||||
<pre><%= user[0].bio %></pre>
|
||||
</form>
|
||||
<div class='area'>
|
||||
<h1>Uploaded Videos</h1>
|
||||
|
|
Loading…
Reference in a new issue