+2
-2
flake.nix
+2
-2
flake.nix
···
81
81
description = "Port to run plonk on";
82
82
};
83
83
cookie_secret = mkOption {
84
-
type = types.string;
84
+
type = types.str;
85
85
default = "00000000000000000000000000000000";
86
86
description = "Cookie secret";
87
87
};
···
104
104
PLONK_PORT = "${toString config.services.plonk.port}";
105
105
PLONK_NODE_ENV = "production";
106
106
PLONK_HOST = "localhost";
107
-
PLONK_PUBLIC_URL = "plonk.li";
107
+
PLONK_PUBLIC_URL = "https://plonk.li";
108
108
PLONK_DB_PATH = "plonk.db";
109
109
PLONK_COOKIE_SECRET = config.services.plonk.cookie_secret;
110
110
};
+2
-1
package.json
+2
-1
package.json
src/assets/NerdIosevka-Regular.woff2
src/assets/NerdIosevka-Regular.woff2
This is a binary file and will not be displayed.
+1
-1
src/auth/client.ts
+1
-1
src/auth/client.ts
···
12
12
client_name: "plonk.li",
13
13
client_id: publicUrl
14
14
? `${url}/client-metadata.json`
15
-
: `http://localhost?redirect_uri=${enc(`${url}/oauth/callback`)}&scope=${enc("atproto transition:generic")}`,
15
+
: `http://${env.PLONK_HOST}?redirect_uri=${enc(`${url}/oauth/callback`)}&scope=${enc("atproto transition:generic")}`,
16
16
client_uri: url,
17
17
redirect_uris: [`${url}/oauth/callback`],
18
18
scope: "atproto transition:generic",
+1
-1
src/mixins/head.pug
+1
-1
src/mixins/head.pug
···
2
2
head
3
3
meta(name="viewport" content="width=device-width, initial-scale=1.0")
4
4
meta(charset='UTF-8')
5
-
title #{title}
5
+
title #{title} · plonk.li
6
6
link(rel="stylesheet", href="/styles.css")
7
7
link(rel="preconnect" href="https://rsms.me/")
8
8
link(rel="stylesheet" href="https://rsms.me/inter/inter.css")
-2
src/mixins/header.pug
-2
src/mixins/header.pug
+3
-2
src/mixins/post.pug
+3
-2
src/mixins/post.pug
···
1
1
mixin post(paste, handle, did)
2
2
div.post
3
3
p
4
-
a(href=`/p/${paste.shortUrl}`)
4
+
a(href=`/p/${paste.shortUrl}`).post-link
5
5
| #{paste.title}
6
6
p.post-info
7
7
| by
···
13
13
| #{paste.lang}
14
14
| ·
15
15
| #{paste.code.split('\n').length} loc
16
-
16
+
| ·
17
+
a(href=`/p/${paste.shortUrl}/#comments`) #{paste.commentCount} #{pluralize(paste.commentCount, 'comment')}
+4
src/mixins/utils.pug
+4
src/mixins/utils.pug
+82
-5
src/public/styles.css
+82
-5
src/public/styles.css
···
1
-
@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;1,100;1,200;1,300;1,400;1,500;1,600;1,700&display=swap');
1
+
@font-face {
2
+
font-family: 'NerdIosevka';
3
+
src: url('../assets/NerdIosevka-Regular.woff2') format('woff2');
4
+
font-weight: normal;
5
+
font-style: monospace;
6
+
}
2
7
3
8
:root {
4
9
/* Light mode colors */
···
28
33
}
29
34
30
35
* {
31
-
font-family: 'IBM Plex Mono', monospace;
36
+
font-family: 'NerdIosevka', monospace;
37
+
font-size: 0.9rem;
32
38
}
33
39
34
40
body {
···
52
58
}
53
59
54
60
pre {
55
-
background-color: var(--bg-color-muted);
56
61
padding: 1rem;
57
62
overflow-x: auto;
58
63
}
59
64
65
+
.comment-body {
66
+
background-color: var(--bg-color);
67
+
padding: 0;
68
+
margin-top: 0.1rem;
69
+
}
70
+
71
+
.comment-info {
72
+
margin-bottom: 0;
73
+
}
74
+
60
75
input, textarea, select, button {
61
76
border: none;
62
77
padding: 1rem;
···
93
108
hr {
94
109
border: none;
95
110
border-top: 1px solid var(--bg-color-muted);
96
-
padding: 1rem;
97
111
}
98
112
99
113
.post-form {
···
127
141
align-self: flex-end;
128
142
}
129
143
144
+
.post-link {
145
+
color: var(--text-color);
146
+
text-decoration: none;
147
+
}
148
+
.post-link:hover {
149
+
text-decoration: underline;
150
+
}
151
+
.post-link:visited {
152
+
color: var(--text-color-muted);
153
+
}
154
+
155
+
.post-info {
156
+
margin-top: 0;
157
+
}
158
+
159
+
.post-info, .comment-info {
160
+
color: var(--text-color-muted);
161
+
}
162
+
.post-info a, .comment-info a {
163
+
color: var(--text-color-muted);
164
+
text-decoration: none;
165
+
}
166
+
.post-info a:visited, .comment-info a:visited {
167
+
color: var(--text-color-muted);
168
+
}
169
+
.post-info a:hover, .comment-info a:hover {
170
+
text-decoration: underline;
171
+
}
172
+
130
173
.timeline, .comments {
131
174
display: flex;
132
175
flex-direction: column;
133
176
gap: 1rem;
177
+
padding-bottom: 1rem;
134
178
}
135
179
136
180
.login-input-title {
···
141
185
flex: 1
142
186
}
143
187
144
-
.header {
188
+
.header, .footer {
145
189
display: flex;
146
190
flex-direction: row;
147
191
justify-content: space-between;
···
154
198
text-indent: 1px;
155
199
text-overflow: '';
156
200
}
201
+
202
+
.code-line {
203
+
display: flex;
204
+
}
205
+
206
+
.code-line-num {
207
+
white-space: pre;
208
+
-webkit-user-select: none;
209
+
user-select: none;
210
+
margin-right: 0.4em;
211
+
padding: 0 0.4em 0 0.4em;
212
+
color: var(--text-color-muted);
213
+
text-align: right;
214
+
}
215
+
216
+
.code-line-content {
217
+
color: var(--text-color);
218
+
}
219
+
220
+
.header, .footer {
221
+
color: var(--text-color);
222
+
}
223
+
224
+
.header a, .header a:visited,
225
+
.footer a, .footer a:visited {
226
+
color: var(--link-color);
227
+
text-decoration: none;
228
+
}
229
+
230
+
.header a:hover,
231
+
.footer a:hover {
232
+
text-decoration: underline;
233
+
}
+40
-12
src/routes.ts
+40
-12
src/routes.ts
···
49
49
export const createRouter = (ctx: Ctx) => {
50
50
const router = express.Router();
51
51
52
+
router.use("/assets", express.static(path.join(__dirname, "assets")));
52
53
// OAuth metadata
53
54
router.get("/client-metadata.json", async (_req, res) => {
54
55
return res.json(ctx.oauthClient.clientMetadata);
···
104
105
const agent = await getSessionAgent(req, res, ctx);
105
106
const pastes = await ctx.db
106
107
.selectFrom("paste")
107
-
.selectAll()
108
-
.orderBy("indexedAt", "desc")
108
+
.leftJoin("comment", "comment.pasteUri", "paste.uri")
109
+
.select([
110
+
"paste.uri",
111
+
"paste.shortUrl",
112
+
"paste.authorDid",
113
+
"paste.code",
114
+
"paste.lang",
115
+
"paste.title",
116
+
"paste.createdAt",
117
+
"paste.indexedAt as pasteIndexedAt",
118
+
ctx.db.fn.count("comment.uri").as("commentCount")
119
+
])
120
+
.groupBy("paste.uri")
121
+
.orderBy("pasteIndexedAt", "desc")
109
122
.limit(25)
110
123
.execute();
111
124
···
129
142
const { authorDid } = req.params;
130
143
const pastes = await ctx.db
131
144
.selectFrom("paste")
132
-
.selectAll()
133
-
.where("authorDid", "=", authorDid)
145
+
.leftJoin("comment", "comment.pasteUri", "paste.uri")
146
+
.select([
147
+
"paste.uri",
148
+
"paste.shortUrl",
149
+
"paste.authorDid as pasteAuthorDid",
150
+
"paste.code",
151
+
"paste.lang",
152
+
"paste.title",
153
+
"paste.createdAt as pasteCreatedAt",
154
+
"paste.indexedAt as pasteIndexedAt",
155
+
ctx.db.fn.count("comment.uri").as("commentCount")
156
+
])
157
+
.groupBy("paste.uri")
158
+
.where("pasteAuthorDid", "=", authorDid)
159
+
.orderBy("pasteCreatedAt", "desc")
134
160
.execute();
135
161
let didHandleMap: Record<string, string> = {};
136
162
didHandleMap[authorDid] = await ctx.resolver.resolveDidToHandle(authorDid);
···
193
219
authorDid: pasteAuthorDid,
194
220
};
195
221
196
-
const comments = ret.map((row) => {
197
-
return {
198
-
uri: row.commentUri,
199
-
authorDid: row.commentAuthorDid,
200
-
body: row.commentBody,
201
-
createdAt: row.commentCreatedAt,
202
-
};
203
-
});
222
+
const comments = ret
223
+
.filter((row) => row.commentUri)
224
+
.map((row) => {
225
+
return {
226
+
uri: row.commentUri,
227
+
authorDid: row.commentAuthorDid,
228
+
body: row.commentBody,
229
+
createdAt: row.commentCreatedAt,
230
+
};
231
+
});
204
232
205
233
const ownAgent = await getSessionAgent(req, res, ctx);
206
234
if (!ownAgent) {
+4
src/views/index.pug
+4
src/views/index.pug
···
1
1
include ../mixins/mkPost
2
2
include ../mixins/head
3
3
include ../mixins/header
4
+
include ../mixins/footer
4
5
include ../mixins/utils
5
6
include ../mixins/post
6
7
···
19
20
"c",
20
21
"c#",
21
22
"c++",
23
+
"cobol",
22
24
].toSorted())
23
25
doctype html
24
26
html
···
34
36
each paste in pastes
35
37
- var handle = didHandleMap[paste.authorDid]
36
38
+post(paste, handle, paste.authorDid)
39
+
40
+
+footer()
+5
-8
src/views/login.pug
+5
-8
src/views/login.pug
···
1
+
include ../mixins/head
2
+
include ../mixins/footer
3
+
1
4
doctype html
2
5
html
3
-
head
4
-
meta(name="viewport" content="width=device-width, initial-scale=1.0")
5
-
meta(charset='UTF-8')
6
-
title login
7
-
link(rel="stylesheet", href="/styles.css")
8
-
link(rel="preconnect" href="https://rsms.me/")
9
-
link(rel="stylesheet" href="https://rsms.me/inter/inter.css")
10
-
script(src="https://cdn.dashjs.org/latest/dash.all.min.js")
6
+
+head("login")
11
7
body
12
8
main#content
13
9
h1 login
···
15
11
div.login-row
16
12
input(type="text" name="handle" placeholder="enter handle" required).login-input-title
17
13
button(type="submit").login-submit-button login
14
+
+footer()
+37
-18
src/views/paste.pug
+37
-18
src/views/paste.pug
···
1
1
- var now = new Date()
2
2
include ../mixins/head
3
3
include ../mixins/header
4
+
include ../mixins/footer
4
5
include ../mixins/utils
5
6
doctype html
6
7
html
7
-
+head(paste.title)
8
+
+head(`${paste.title} · ${didHandleMap[paste.authorDid]}`)
8
9
body
9
10
main#content
10
11
+header(ownDid, didHandleMap)
11
12
h1 #{paste.title}
12
-
p
13
-
| by @#{didHandleMap[paste.authorDid]} ·
13
+
p.post-info
14
+
| @#{didHandleMap[paste.authorDid]} ·
14
15
| #{timeDifference(now, Date.parse(paste.createdAt))} ago ·
15
16
| #{paste.lang} ·
16
17
| #{paste.code.split('\n').length} loc ·
17
18
a(href=`/r/${paste.shortUrl}`) raw
19
+
| ·
20
+
| #{comments.length} #{pluralize(comments.length, 'comment')}
18
21
pre
19
-
| #{paste.code}
22
+
code
23
+
- var lines = paste.code.split(/\r?\n|\r|\n/g)
24
+
- var tot_chars = lines.length.toString().length
25
+
each line, idx in lines
26
+
span.code-line
27
+
span.code-line-num(id=`L${idx + 1}` style=`min-width: ${tot_chars}ch;`)
28
+
| #{idx + 1}
29
+
span.code-line-content #{line}
20
30
hr
21
31
22
-
div.comments
23
-
each comment in comments
24
-
div.comment(id=`${encodeURIComponent(comment.uri)}`)
25
-
p
26
-
| by @#{didHandleMap[comment.authorDid]} ·
27
-
| #{timeDifference(now, Date.parse(paste.createdAt))} ago
28
-
p
29
-
| #{comment.body}
30
-
hr
32
+
if comments.length != 0
33
+
h1(id="comments") comments
34
+
div.comments
35
+
each comment in comments
36
+
div.comment(id=`${encodeURIComponent(comment.uri)}`)
37
+
p.comment-info
38
+
a(href=`/u/${comment.authorDid}`)
39
+
| @#{didHandleMap[comment.authorDid]}
40
+
| ·
41
+
| #{timeDifference(now, Date.parse(paste.createdAt))} ago
42
+
pre.comment-body #{comment.body}
43
+
44
+
if ownDid
45
+
form(action=`/${encodeURIComponent(paste.uri)}/comment` method="post").post-form
46
+
div.post-row
47
+
textarea#code(name="comment" rows="5" placeholder="add a comment" required).post-input-code
31
48
32
-
form(action=`/${encodeURIComponent(paste.uri)}/comment` method="post").post-form
33
-
div.post-row
34
-
textarea#code(name="comment" rows="5" placeholder="add a comment" required).post-input-code
49
+
div.post-submit-row
50
+
button(type="submit").post-input-submit zonk!
51
+
else
52
+
p
53
+
a(href="/login") login
54
+
| to post a comment
35
55
36
-
div.post-submit-row
37
-
button(type="submit").post-input-submit zonk!
56
+
+footer()
+3
src/views/user.pug
+3
src/views/user.pug
···
2
2
- var handle = didHandleMap[authorDid]
3
3
include ../mixins/head
4
4
include ../mixins/header
5
+
include ../mixins/footer
5
6
include ../mixins/utils
6
7
include ../mixins/post
7
8
doctype html
···
14
15
div.timeline
15
16
each paste in pastes
16
17
+post(paste, handle, authorDid)
18
+
19
+
+footer()
+463
x
+463
x
···
1
+
From 489bb110616aa4da596aed7ae0a048c919ed333e Mon Sep 17 00:00:00 2001
2
+
From: Akshay <nerdy@peppe.rs>
3
+
Date: Thu, 26 Dec 2024 19:19:37 +0000
4
+
Subject: [PATCH 1/3] add footer, comments, linenrs etc
5
+
6
+
---
7
+
src/mixins/footer.pug | 9 +++++++++
8
+
src/mixins/post.pug | 3 ++-
9
+
src/mixins/utils.pug | 4 ++++
10
+
src/public/styles.css | 21 +++++++++++++++++++--
11
+
src/routes.ts | 33 +++++++++++++++++++++++++++++----
12
+
src/views/index.pug | 3 +++
13
+
src/views/paste.pug | 28 +++++++++++++++++++++-------
14
+
7 files changed, 87 insertions(+), 14 deletions(-)
15
+
create mode 100644 src/mixins/footer.pug
16
+
17
+
diff --git a/src/mixins/footer.pug b/src/mixins/footer.pug
18
+
new file mode 100644
19
+
index 0000000..be71086
20
+
--- /dev/null
21
+
+++ b/src/mixins/footer.pug
22
+
@@ -0,0 +1,9 @@
23
+
+mixin footer()
24
+
+ hr
25
+
+ div.footer
26
+
+ div.left-side
27
+
+ div.right-side
28
+
+ p
29
+
+ | made by
30
+
+ a(href="https://bsky.app/profile/oppi.li") @oppi.li
31
+
+
32
+
diff --git a/src/mixins/post.pug b/src/mixins/post.pug
33
+
index 77d78aa..e98bcf8 100644
34
+
--- a/src/mixins/post.pug
35
+
+++ b/src/mixins/post.pug
36
+
@@ -13,4 +13,5 @@ mixin post(paste, handle, did)
37
+
| #{paste.lang}
38
+
| ·
39
+
| #{paste.code.split('\n').length} loc
40
+
-
41
+
+ | ·
42
+
+ a(href=`/p/${paste.shortUrl}/#comments`) #{paste.commentCount} #{pluralize(paste.commentCount, 'comment')}
43
+
diff --git a/src/mixins/utils.pug b/src/mixins/utils.pug
44
+
index 857bddd..08507d3 100644
45
+
--- a/src/mixins/utils.pug
46
+
+++ b/src/mixins/utils.pug
47
+
@@ -2,6 +2,10 @@
48
+
function randInt(min, max) {
49
+
return Math.floor(Math.random() * (max - min + 1)) + min;
50
+
}
51
+
+-
52
+
+ function pluralize(count, noun) {
53
+
+ return count==1?noun:`${noun}s`;
54
+
+ }
55
+
-
56
+
function timeDifference(current, previous) {
57
+
if (!current || !previous) {
58
+
diff --git a/src/public/styles.css b/src/public/styles.css
59
+
index f88b533..6f80f5f 100644
60
+
--- a/src/public/styles.css
61
+
+++ b/src/public/styles.css
62
+
@@ -104,7 +104,6 @@ textarea {
63
+
hr {
64
+
border: none;
65
+
border-top: 1px solid var(--bg-color-muted);
66
+
- padding: 1rem;
67
+
}
68
+
69
+
.post-form {
70
+
@@ -152,7 +151,7 @@ hr {
71
+
flex: 1
72
+
}
73
+
74
+
-.header {
75
+
+.header, .footer {
76
+
display: flex;
77
+
flex-direction: row;
78
+
justify-content: space-between;
79
+
@@ -165,3 +164,21 @@ select {
80
+
text-indent: 1px;
81
+
text-overflow: '';
82
+
}
83
+
+
84
+
+.code-line {
85
+
+ display: flex;
86
+
+}
87
+
+
88
+
+.code-line-num {
89
+
+ white-space: pre;
90
+
+ -webkit-user-select: none;
91
+
+ user-select: none;
92
+
+ margin-right: 0.4em;
93
+
+ padding: 0 0.4em 0 0.4em;
94
+
+ color: var(--text-color-muted);
95
+
+ text-align: right;
96
+
+}
97
+
+
98
+
+.code-line-content {
99
+
+ color: var(--text-color);
100
+
+}
101
+
diff --git a/src/routes.ts b/src/routes.ts
102
+
index 70f931d..17fa00e 100644
103
+
--- a/src/routes.ts
104
+
+++ b/src/routes.ts
105
+
@@ -105,8 +105,20 @@ export const createRouter = (ctx: Ctx) => {
106
+
const agent = await getSessionAgent(req, res, ctx);
107
+
const pastes = await ctx.db
108
+
.selectFrom("paste")
109
+
- .selectAll()
110
+
- .orderBy("indexedAt", "desc")
111
+
+ .leftJoin("comment", "comment.pasteUri", "paste.uri")
112
+
+ .select([
113
+
+ "paste.uri",
114
+
+ "paste.shortUrl",
115
+
+ "paste.authorDid",
116
+
+ "paste.code",
117
+
+ "paste.lang",
118
+
+ "paste.title",
119
+
+ "paste.createdAt",
120
+
+ "paste.indexedAt as pasteIndexedAt",
121
+
+ ctx.db.fn.count("comment.uri").as("commentCount")
122
+
+ ])
123
+
+ .groupBy("paste.uri")
124
+
+ .orderBy("pasteIndexedAt", "desc")
125
+
.limit(25)
126
+
.execute();
127
+
128
+
@@ -130,8 +142,21 @@ export const createRouter = (ctx: Ctx) => {
129
+
const { authorDid } = req.params;
130
+
const pastes = await ctx.db
131
+
.selectFrom("paste")
132
+
- .selectAll()
133
+
- .where("authorDid", "=", authorDid)
134
+
+ .leftJoin("comment", "comment.pasteUri", "paste.uri")
135
+
+ .select([
136
+
+ "paste.uri",
137
+
+ "paste.shortUrl",
138
+
+ "paste.authorDid as pasteAuthorDid",
139
+
+ "paste.code",
140
+
+ "paste.lang",
141
+
+ "paste.title",
142
+
+ "paste.createdAt as pasteCreatedAt",
143
+
+ "paste.indexedAt as pasteIndexedAt",
144
+
+ ctx.db.fn.count("comment.uri").as("commentCount")
145
+
+ ])
146
+
+ .groupBy("paste.uri")
147
+
+ .where("pasteAuthorDid", "=", authorDid)
148
+
+ .orderBy("pasteCreatedAt", "desc")
149
+
.execute();
150
+
let didHandleMap: Record<string, string> = {};
151
+
didHandleMap[authorDid] = await ctx.resolver.resolveDidToHandle(authorDid);
152
+
diff --git a/src/views/index.pug b/src/views/index.pug
153
+
index 3443deb..e04403d 100644
154
+
--- a/src/views/index.pug
155
+
+++ b/src/views/index.pug
156
+
@@ -1,6 +1,7 @@
157
+
include ../mixins/mkPost
158
+
include ../mixins/head
159
+
include ../mixins/header
160
+
+include ../mixins/footer
161
+
include ../mixins/utils
162
+
include ../mixins/post
163
+
164
+
@@ -19,6 +20,7 @@ include ../mixins/post
165
+
"c",
166
+
"c#",
167
+
"c++",
168
+
+ "cobol",
169
+
].toSorted())
170
+
doctype html
171
+
html
172
+
@@ -34,3 +36,4 @@ html
173
+
each paste in pastes
174
+
- var handle = didHandleMap[paste.authorDid]
175
+
+post(paste, handle, paste.authorDid)
176
+
+ +footer()
177
+
diff --git a/src/views/paste.pug b/src/views/paste.pug
178
+
index 29516d3..f8a0906 100644
179
+
--- a/src/views/paste.pug
180
+
+++ b/src/views/paste.pug
181
+
@@ -15,12 +15,21 @@ html
182
+
| #{paste.lang} ·
183
+
| #{paste.code.split('\n').length} loc ·
184
+
a(href=`/r/${paste.shortUrl}`) raw
185
+
+ | ·
186
+
+ | #{comments.length} #{pluralize(comments.length, 'comment')}
187
+
pre
188
+
- | #{paste.code}
189
+
+ code
190
+
+ - var lines = paste.code.split(/\r?\n|\r|\n/g)
191
+
+ - var tot_chars = lines.length.toString().length
192
+
+ each line, idx in lines
193
+
+ span.code-line
194
+
+ span.code-line-num(id=`L${idx + 1}` style=`min-width: ${tot_chars}ch;`)
195
+
+ | #{idx + 1}
196
+
+ span.code-line-content #{line}
197
+
hr
198
+
199
+
if comments.length != 0
200
+
- h1 comments
201
+
+ h1(id="comments") comments
202
+
div.comments
203
+
each comment in comments
204
+
div.comment(id=`${encodeURIComponent(comment.uri)}`)
205
+
@@ -33,9 +42,14 @@ html
206
+
pre.comment-body #{comment.body}
207
+
hr
208
+
209
+
- form(action=`/${encodeURIComponent(paste.uri)}/comment` method="post").post-form
210
+
- div.post-row
211
+
- textarea#code(name="comment" rows="5" placeholder="add a comment" required).post-input-code
212
+
+ if ownDid
213
+
+ form(action=`/${encodeURIComponent(paste.uri)}/comment` method="post").post-form
214
+
+ div.post-row
215
+
+ textarea#code(name="comment" rows="5" placeholder="add a comment" required).post-input-code
216
+
217
+
- div.post-submit-row
218
+
- button(type="submit").post-input-submit zonk!
219
+
+ div.post-submit-row
220
+
+ button(type="submit").post-input-submit zonk!
221
+
+ else
222
+
+ p
223
+
+ a(href="/login") login
224
+
+ | to post a comment
225
+
--
226
+
2.47.0
227
+
228
+
From 436f4d5e8912c50068d8c70e623a23ce2ca9e6e7 Mon Sep 17 00:00:00 2001
229
+
From: Akshay <nerdy@peppe.rs>
230
+
Date: Thu, 26 Dec 2024 21:12:07 +0000
231
+
Subject: [PATCH 2/3] footer everywhere
232
+
233
+
---
234
+
src/views/index.pug | 1 +
235
+
src/views/login.pug | 2 ++
236
+
src/views/paste.pug | 6 ++++--
237
+
src/views/user.pug | 3 +++
238
+
4 files changed, 10 insertions(+), 2 deletions(-)
239
+
240
+
diff --git a/src/views/index.pug b/src/views/index.pug
241
+
index e04403d..bc9085a 100644
242
+
--- a/src/views/index.pug
243
+
+++ b/src/views/index.pug
244
+
@@ -36,4 +36,5 @@ html
245
+
each paste in pastes
246
+
- var handle = didHandleMap[paste.authorDid]
247
+
+post(paste, handle, paste.authorDid)
248
+
+
249
+
+footer()
250
+
diff --git a/src/views/login.pug b/src/views/login.pug
251
+
index 55aa048..b5a35e0 100644
252
+
--- a/src/views/login.pug
253
+
+++ b/src/views/login.pug
254
+
@@ -1,4 +1,5 @@
255
+
include ../mixins/head
256
+
+include ../mixins/footer
257
+
258
+
doctype html
259
+
html
260
+
@@ -10,3 +11,4 @@ html
261
+
div.login-row
262
+
input(type="text" name="handle" placeholder="enter handle" required).login-input-title
263
+
button(type="submit").login-submit-button login
264
+
+ +footer()
265
+
diff --git a/src/views/paste.pug b/src/views/paste.pug
266
+
index f8a0906..653c02e 100644
267
+
--- a/src/views/paste.pug
268
+
+++ b/src/views/paste.pug
269
+
@@ -1,6 +1,7 @@
270
+
- var now = new Date()
271
+
include ../mixins/head
272
+
include ../mixins/header
273
+
+include ../mixins/footer
274
+
include ../mixins/utils
275
+
doctype html
276
+
html
277
+
@@ -40,7 +41,6 @@ html
278
+
| #{timeDifference(now, Date.parse(paste.createdAt))} ago
279
+
p
280
+
pre.comment-body #{comment.body}
281
+
- hr
282
+
283
+
if ownDid
284
+
form(action=`/${encodeURIComponent(paste.uri)}/comment` method="post").post-form
285
+
@@ -49,7 +49,9 @@ html
286
+
287
+
div.post-submit-row
288
+
button(type="submit").post-input-submit zonk!
289
+
- else
290
+
+ else
291
+
p
292
+
a(href="/login") login
293
+
| to post a comment
294
+
+
295
+
+ +footer()
296
+
diff --git a/src/views/user.pug b/src/views/user.pug
297
+
index 3523e16..b2b2743 100644
298
+
--- a/src/views/user.pug
299
+
+++ b/src/views/user.pug
300
+
@@ -2,6 +2,7 @@
301
+
- var handle = didHandleMap[authorDid]
302
+
include ../mixins/head
303
+
include ../mixins/header
304
+
+include ../mixins/footer
305
+
include ../mixins/utils
306
+
include ../mixins/post
307
+
doctype html
308
+
@@ -14,3 +15,5 @@ html
309
+
div.timeline
310
+
each paste in pastes
311
+
+post(paste, handle, authorDid)
312
+
+
313
+
+ +footer()
314
+
--
315
+
2.47.0
316
+
317
+
From a717f0702e818515e34187cde86c15c00d2e66ba Mon Sep 17 00:00:00 2001
318
+
From: Akshay <nerdy@peppe.rs>
319
+
Date: Thu, 26 Dec 2024 23:14:37 +0000
320
+
Subject: [PATCH 3/3] stylin for links
321
+
322
+
---
323
+
src/mixins/post.pug | 2 +-
324
+
src/public/styles.css | 51 ++++++++++++++++++++++++++++++++++++++++++-
325
+
src/views/paste.pug | 9 ++++----
326
+
3 files changed, 55 insertions(+), 7 deletions(-)
327
+
328
+
diff --git a/src/mixins/post.pug b/src/mixins/post.pug
329
+
index e98bcf8..51af1ff 100644
330
+
--- a/src/mixins/post.pug
331
+
+++ b/src/mixins/post.pug
332
+
@@ -1,7 +1,7 @@
333
+
mixin post(paste, handle, did)
334
+
div.post
335
+
p
336
+
- a(href=`/p/${paste.shortUrl}`)
337
+
+ a(href=`/p/${paste.shortUrl}`).post-link
338
+
| #{paste.title}
339
+
p.post-info
340
+
| by
341
+
diff --git a/src/public/styles.css b/src/public/styles.css
342
+
index 6f80f5f..b153f92 100644
343
+
--- a/src/public/styles.css
344
+
+++ b/src/public/styles.css
345
+
@@ -58,7 +58,6 @@ a:visited {
346
+
}
347
+
348
+
pre {
349
+
- background-color: var(--bg-color-muted);
350
+
padding: 1rem;
351
+
overflow-x: auto;
352
+
}
353
+
@@ -66,6 +65,11 @@ pre {
354
+
.comment-body {
355
+
background-color: var(--bg-color);
356
+
padding: 0;
357
+
+ margin-top: 0.1rem;
358
+
+}
359
+
+
360
+
+.comment-info {
361
+
+ margin-bottom: 0;
362
+
}
363
+
364
+
input, textarea, select, button {
365
+
@@ -137,10 +141,40 @@ hr {
366
+
align-self: flex-end;
367
+
}
368
+
369
+
+.post-link {
370
+
+ color: var(--text-color);
371
+
+ text-decoration: none;
372
+
+}
373
+
+.post-link:hover {
374
+
+ text-decoration: underline;
375
+
+}
376
+
+.post-link:visited {
377
+
+ color: var(--text-color-muted);
378
+
+}
379
+
+
380
+
+.post-info {
381
+
+ margin-top: 0;
382
+
+}
383
+
+
384
+
+.post-info, .comment-info {
385
+
+ color: var(--text-color-muted);
386
+
+}
387
+
+.post-info a, .comment-info a {
388
+
+ color: var(--text-color-muted);
389
+
+ text-decoration: none;
390
+
+}
391
+
+.post-info a:visited, .comment-info a:visited {
392
+
+ color: var(--text-color-muted);
393
+
+}
394
+
+.post-info a:hover, .comment-info a:hover {
395
+
+ text-decoration: underline;
396
+
+}
397
+
+
398
+
.timeline, .comments {
399
+
display: flex;
400
+
flex-direction: column;
401
+
gap: 1rem;
402
+
+ padding-bottom: 1rem;
403
+
}
404
+
405
+
.login-input-title {
406
+
@@ -182,3 +216,18 @@ select {
407
+
.code-line-content {
408
+
color: var(--text-color);
409
+
}
410
+
+
411
+
+.header, .footer {
412
+
+ color: var(--text-color);
413
+
+}
414
+
+
415
+
+.header a, .header a:visited,
416
+
+.footer a, .footer a:visited {
417
+
+ color: var(--link-color);
418
+
+ text-decoration: none;
419
+
+}
420
+
+
421
+
+.header a:hover,
422
+
+.footer a:hover {
423
+
+ text-decoration: underline;
424
+
+}
425
+
diff --git a/src/views/paste.pug b/src/views/paste.pug
426
+
index 653c02e..3014107 100644
427
+
--- a/src/views/paste.pug
428
+
+++ b/src/views/paste.pug
429
+
@@ -10,13 +10,13 @@ html
430
+
main#content
431
+
+header(ownDid, didHandleMap)
432
+
h1 #{paste.title}
433
+
- p
434
+
+ p.post-info
435
+
| @#{didHandleMap[paste.authorDid]} ·
436
+
| #{timeDifference(now, Date.parse(paste.createdAt))} ago ·
437
+
| #{paste.lang} ·
438
+
| #{paste.code.split('\n').length} loc ·
439
+
a(href=`/r/${paste.shortUrl}`) raw
440
+
- | ·
441
+
+ | ·
442
+
| #{comments.length} #{pluralize(comments.length, 'comment')}
443
+
pre
444
+
code
445
+
@@ -34,13 +34,12 @@ html
446
+
div.comments
447
+
each comment in comments
448
+
div.comment(id=`${encodeURIComponent(comment.uri)}`)
449
+
- p
450
+
+ p.comment-info
451
+
a(href=`/u/${comment.authorDid}`)
452
+
| @#{didHandleMap[comment.authorDid]}
453
+
| ·
454
+
| #{timeDifference(now, Date.parse(paste.createdAt))} ago
455
+
- p
456
+
- pre.comment-body #{comment.body}
457
+
+ pre.comment-body #{comment.body}
458
+
459
+
if ownDid
460
+
form(action=`/${encodeURIComponent(paste.uri)}/comment` method="post").post-form
461
+
--
462
+
2.47.0
463
+
+465
y
+465
y
···
1
+
From 6df2fc36269c7114fb845fa0ac667e08f6e7d09b Mon Sep 17 00:00:00 2001
2
+
From: Akshay <nerdy@peppe.rs>
3
+
Date: Thu, 26 Dec 2024 19:19:37 +0000
4
+
Subject: [PATCH 1/3] add footer, comments, linenrs etc
5
+
6
+
---
7
+
src/mixins/footer.pug | 9 +++++++++
8
+
src/mixins/post.pug | 3 ++-
9
+
src/mixins/utils.pug | 4 ++++
10
+
src/public/styles.css | 21 +++++++++++++++++++--
11
+
src/routes.ts | 33 +++++++++++++++++++++++++++++----
12
+
src/views/index.pug | 3 +++
13
+
src/views/paste.pug | 28 +++++++++++++++++++++-------
14
+
7 files changed, 87 insertions(+), 14 deletions(-)
15
+
create mode 100644 src/mixins/footer.pug
16
+
17
+
diff --git a/src/mixins/footer.pug b/src/mixins/footer.pug
18
+
new file mode 100644
19
+
index 0000000..be71086
20
+
--- /dev/null
21
+
+++ b/src/mixins/footer.pug
22
+
@@ -0,0 +1,9 @@
23
+
+mixin footer()
24
+
+ hr
25
+
+ div.footer
26
+
+ div.left-side
27
+
+ div.right-side
28
+
+ p
29
+
+ | made by
30
+
+ a(href="https://bsky.app/profile/oppi.li") @oppi.li
31
+
+
32
+
diff --git a/src/mixins/post.pug b/src/mixins/post.pug
33
+
index 77d78aa..e98bcf8 100644
34
+
--- a/src/mixins/post.pug
35
+
+++ b/src/mixins/post.pug
36
+
@@ -13,4 +13,5 @@ mixin post(paste, handle, did)
37
+
| #{paste.lang}
38
+
| ·
39
+
| #{paste.code.split('\n').length} loc
40
+
-
41
+
+ | ·
42
+
+ a(href=`/p/${paste.shortUrl}/#comments`) #{paste.commentCount} #{pluralize(paste.commentCount, 'comment')}
43
+
diff --git a/src/mixins/utils.pug b/src/mixins/utils.pug
44
+
index 857bddd..08507d3 100644
45
+
--- a/src/mixins/utils.pug
46
+
+++ b/src/mixins/utils.pug
47
+
@@ -2,6 +2,10 @@
48
+
function randInt(min, max) {
49
+
return Math.floor(Math.random() * (max - min + 1)) + min;
50
+
}
51
+
+-
52
+
+ function pluralize(count, noun) {
53
+
+ return count==1?noun:`${noun}s`;
54
+
+ }
55
+
-
56
+
function timeDifference(current, previous) {
57
+
if (!current || !previous) {
58
+
diff --git a/src/public/styles.css b/src/public/styles.css
59
+
index f88b533..6f80f5f 100644
60
+
--- a/src/public/styles.css
61
+
+++ b/src/public/styles.css
62
+
@@ -104,7 +104,6 @@ textarea {
63
+
hr {
64
+
border: none;
65
+
border-top: 1px solid var(--bg-color-muted);
66
+
- padding: 1rem;
67
+
}
68
+
69
+
.post-form {
70
+
@@ -152,7 +151,7 @@ hr {
71
+
flex: 1
72
+
}
73
+
74
+
-.header {
75
+
+.header, .footer {
76
+
display: flex;
77
+
flex-direction: row;
78
+
justify-content: space-between;
79
+
@@ -165,3 +164,21 @@ select {
80
+
text-indent: 1px;
81
+
text-overflow: '';
82
+
}
83
+
+
84
+
+.code-line {
85
+
+ display: flex;
86
+
+}
87
+
+
88
+
+.code-line-num {
89
+
+ white-space: pre;
90
+
+ -webkit-user-select: none;
91
+
+ user-select: none;
92
+
+ margin-right: 0.4em;
93
+
+ padding: 0 0.4em 0 0.4em;
94
+
+ color: var(--text-color-muted);
95
+
+ text-align: right;
96
+
+}
97
+
+
98
+
+.code-line-content {
99
+
+ color: var(--text-color);
100
+
+}
101
+
diff --git a/src/routes.ts b/src/routes.ts
102
+
index 70f931d..17fa00e 100644
103
+
--- a/src/routes.ts
104
+
+++ b/src/routes.ts
105
+
@@ -105,8 +105,20 @@ export const createRouter = (ctx: Ctx) => {
106
+
const agent = await getSessionAgent(req, res, ctx);
107
+
const pastes = await ctx.db
108
+
.selectFrom("paste")
109
+
- .selectAll()
110
+
- .orderBy("indexedAt", "desc")
111
+
+ .leftJoin("comment", "comment.pasteUri", "paste.uri")
112
+
+ .select([
113
+
+ "paste.uri",
114
+
+ "paste.shortUrl",
115
+
+ "paste.authorDid",
116
+
+ "paste.code",
117
+
+ "paste.lang",
118
+
+ "paste.title",
119
+
+ "paste.createdAt",
120
+
+ "paste.indexedAt as pasteIndexedAt",
121
+
+ ctx.db.fn.count("comment.uri").as("commentCount")
122
+
+ ])
123
+
+ .groupBy("paste.uri")
124
+
+ .orderBy("pasteIndexedAt", "desc")
125
+
.limit(25)
126
+
.execute();
127
+
128
+
@@ -130,8 +142,21 @@ export const createRouter = (ctx: Ctx) => {
129
+
const { authorDid } = req.params;
130
+
const pastes = await ctx.db
131
+
.selectFrom("paste")
132
+
- .selectAll()
133
+
- .where("authorDid", "=", authorDid)
134
+
+ .leftJoin("comment", "comment.pasteUri", "paste.uri")
135
+
+ .select([
136
+
+ "paste.uri",
137
+
+ "paste.shortUrl",
138
+
+ "paste.authorDid as pasteAuthorDid",
139
+
+ "paste.code",
140
+
+ "paste.lang",
141
+
+ "paste.title",
142
+
+ "paste.createdAt as pasteCreatedAt",
143
+
+ "paste.indexedAt as pasteIndexedAt",
144
+
+ ctx.db.fn.count("comment.uri").as("commentCount")
145
+
+ ])
146
+
+ .groupBy("paste.uri")
147
+
+ .where("pasteAuthorDid", "=", authorDid)
148
+
+ .orderBy("pasteCreatedAt", "desc")
149
+
.execute();
150
+
let didHandleMap: Record<string, string> = {};
151
+
didHandleMap[authorDid] = await ctx.resolver.resolveDidToHandle(authorDid);
152
+
diff --git a/src/views/index.pug b/src/views/index.pug
153
+
index 3443deb..e04403d 100644
154
+
--- a/src/views/index.pug
155
+
+++ b/src/views/index.pug
156
+
@@ -1,6 +1,7 @@
157
+
include ../mixins/mkPost
158
+
include ../mixins/head
159
+
include ../mixins/header
160
+
+include ../mixins/footer
161
+
include ../mixins/utils
162
+
include ../mixins/post
163
+
164
+
@@ -19,6 +20,7 @@ include ../mixins/post
165
+
"c",
166
+
"c#",
167
+
"c++",
168
+
+ "cobol",
169
+
].toSorted())
170
+
doctype html
171
+
html
172
+
@@ -34,3 +36,4 @@ html
173
+
each paste in pastes
174
+
- var handle = didHandleMap[paste.authorDid]
175
+
+post(paste, handle, paste.authorDid)
176
+
+ +footer()
177
+
diff --git a/src/views/paste.pug b/src/views/paste.pug
178
+
index 29516d3..f8a0906 100644
179
+
--- a/src/views/paste.pug
180
+
+++ b/src/views/paste.pug
181
+
@@ -15,12 +15,21 @@ html
182
+
| #{paste.lang} ·
183
+
| #{paste.code.split('\n').length} loc ·
184
+
a(href=`/r/${paste.shortUrl}`) raw
185
+
+ | ·
186
+
+ | #{comments.length} #{pluralize(comments.length, 'comment')}
187
+
pre
188
+
- | #{paste.code}
189
+
+ code
190
+
+ - var lines = paste.code.split(/\r?\n|\r|\n/g)
191
+
+ - var tot_chars = lines.length.toString().length
192
+
+ each line, idx in lines
193
+
+ span.code-line
194
+
+ span.code-line-num(id=`L${idx + 1}` style=`min-width: ${tot_chars}ch;`)
195
+
+ | #{idx + 1}
196
+
+ span.code-line-content #{line}
197
+
hr
198
+
199
+
if comments.length != 0
200
+
- h1 comments
201
+
+ h1(id="comments") comments
202
+
div.comments
203
+
each comment in comments
204
+
div.comment(id=`${encodeURIComponent(comment.uri)}`)
205
+
@@ -33,9 +42,14 @@ html
206
+
pre.comment-body #{comment.body}
207
+
hr
208
+
209
+
- form(action=`/${encodeURIComponent(paste.uri)}/comment` method="post").post-form
210
+
- div.post-row
211
+
- textarea#code(name="comment" rows="5" placeholder="add a comment" required).post-input-code
212
+
+ if ownDid
213
+
+ form(action=`/${encodeURIComponent(paste.uri)}/comment` method="post").post-form
214
+
+ div.post-row
215
+
+ textarea#code(name="comment" rows="5" placeholder="add a comment" required).post-input-code
216
+
217
+
- div.post-submit-row
218
+
- button(type="submit").post-input-submit zonk!
219
+
+ div.post-submit-row
220
+
+ button(type="submit").post-input-submit zonk!
221
+
+ else
222
+
+ p
223
+
+ a(href="/login") login
224
+
+ | to post a comment
225
+
--
226
+
2.47.0
227
+
228
+
229
+
From ccd3269be5d287b627c8badc96bd0ce5f0d3a0bf Mon Sep 17 00:00:00 2001
230
+
From: Akshay <nerdy@peppe.rs>
231
+
Date: Thu, 26 Dec 2024 21:12:07 +0000
232
+
Subject: [PATCH 2/3] footer everywhere
233
+
234
+
---
235
+
src/views/index.pug | 1 +
236
+
src/views/login.pug | 2 ++
237
+
src/views/paste.pug | 6 ++++--
238
+
src/views/user.pug | 3 +++
239
+
4 files changed, 10 insertions(+), 2 deletions(-)
240
+
241
+
diff --git a/src/views/index.pug b/src/views/index.pug
242
+
index e04403d..bc9085a 100644
243
+
--- a/src/views/index.pug
244
+
+++ b/src/views/index.pug
245
+
@@ -36,4 +36,5 @@ html
246
+
each paste in pastes
247
+
- var handle = didHandleMap[paste.authorDid]
248
+
+post(paste, handle, paste.authorDid)
249
+
+
250
+
+footer()
251
+
diff --git a/src/views/login.pug b/src/views/login.pug
252
+
index 55aa048..b5a35e0 100644
253
+
--- a/src/views/login.pug
254
+
+++ b/src/views/login.pug
255
+
@@ -1,4 +1,5 @@
256
+
include ../mixins/head
257
+
+include ../mixins/footer
258
+
259
+
doctype html
260
+
html
261
+
@@ -10,3 +11,4 @@ html
262
+
div.login-row
263
+
input(type="text" name="handle" placeholder="enter handle" required).login-input-title
264
+
button(type="submit").login-submit-button login
265
+
+ +footer()
266
+
diff --git a/src/views/paste.pug b/src/views/paste.pug
267
+
index f8a0906..653c02e 100644
268
+
--- a/src/views/paste.pug
269
+
+++ b/src/views/paste.pug
270
+
@@ -1,6 +1,7 @@
271
+
- var now = new Date()
272
+
include ../mixins/head
273
+
include ../mixins/header
274
+
+include ../mixins/footer
275
+
include ../mixins/utils
276
+
doctype html
277
+
html
278
+
@@ -40,7 +41,6 @@ html
279
+
| #{timeDifference(now, Date.parse(paste.createdAt))} ago
280
+
p
281
+
pre.comment-body #{comment.body}
282
+
- hr
283
+
284
+
if ownDid
285
+
form(action=`/${encodeURIComponent(paste.uri)}/comment` method="post").post-form
286
+
@@ -49,7 +49,9 @@ html
287
+
288
+
div.post-submit-row
289
+
button(type="submit").post-input-submit zonk!
290
+
- else
291
+
+ else
292
+
p
293
+
a(href="/login") login
294
+
| to post a comment
295
+
+
296
+
+ +footer()
297
+
diff --git a/src/views/user.pug b/src/views/user.pug
298
+
index 3523e16..b2b2743 100644
299
+
--- a/src/views/user.pug
300
+
+++ b/src/views/user.pug
301
+
@@ -2,6 +2,7 @@
302
+
- var handle = didHandleMap[authorDid]
303
+
include ../mixins/head
304
+
include ../mixins/header
305
+
+include ../mixins/footer
306
+
include ../mixins/utils
307
+
include ../mixins/post
308
+
doctype html
309
+
@@ -14,3 +15,5 @@ html
310
+
div.timeline
311
+
each paste in pastes
312
+
+post(paste, handle, authorDid)
313
+
+
314
+
+ +footer()
315
+
--
316
+
2.47.0
317
+
318
+
319
+
From 0d1ee81ee0630ca852f51a9a49293fb7d0fc7a67 Mon Sep 17 00:00:00 2001
320
+
From: Akshay <nerdy@peppe.rs>
321
+
Date: Thu, 26 Dec 2024 23:14:37 +0000
322
+
Subject: [PATCH 3/3] stylin for links
323
+
324
+
---
325
+
src/mixins/post.pug | 2 +-
326
+
src/public/styles.css | 51 ++++++++++++++++++++++++++++++++++++++++++-
327
+
src/views/paste.pug | 9 ++++----
328
+
3 files changed, 55 insertions(+), 7 deletions(-)
329
+
330
+
diff --git a/src/mixins/post.pug b/src/mixins/post.pug
331
+
index e98bcf8..51af1ff 100644
332
+
--- a/src/mixins/post.pug
333
+
+++ b/src/mixins/post.pug
334
+
@@ -1,7 +1,7 @@
335
+
mixin post(paste, handle, did)
336
+
div.post
337
+
p
338
+
- a(href=`/p/${paste.shortUrl}`)
339
+
+ a(href=`/p/${paste.shortUrl}`).post-link
340
+
| #{paste.title}
341
+
p.post-info
342
+
| by
343
+
diff --git a/src/public/styles.css b/src/public/styles.css
344
+
index 6f80f5f..b153f92 100644
345
+
--- a/src/public/styles.css
346
+
+++ b/src/public/styles.css
347
+
@@ -58,7 +58,6 @@ a:visited {
348
+
}
349
+
350
+
pre {
351
+
- background-color: var(--bg-color-muted);
352
+
padding: 1rem;
353
+
overflow-x: auto;
354
+
}
355
+
@@ -66,6 +65,11 @@ pre {
356
+
.comment-body {
357
+
background-color: var(--bg-color);
358
+
padding: 0;
359
+
+ margin-top: 0.1rem;
360
+
+}
361
+
+
362
+
+.comment-info {
363
+
+ margin-bottom: 0;
364
+
}
365
+
366
+
input, textarea, select, button {
367
+
@@ -137,10 +141,40 @@ hr {
368
+
align-self: flex-end;
369
+
}
370
+
371
+
+.post-link {
372
+
+ color: var(--text-color);
373
+
+ text-decoration: none;
374
+
+}
375
+
+.post-link:hover {
376
+
+ text-decoration: underline;
377
+
+}
378
+
+.post-link:visited {
379
+
+ color: var(--text-color-muted);
380
+
+}
381
+
+
382
+
+.post-info {
383
+
+ margin-top: 0;
384
+
+}
385
+
+
386
+
+.post-info, .comment-info {
387
+
+ color: var(--text-color-muted);
388
+
+}
389
+
+.post-info a, .comment-info a {
390
+
+ color: var(--text-color-muted);
391
+
+ text-decoration: none;
392
+
+}
393
+
+.post-info a:visited, .comment-info a:visited {
394
+
+ color: var(--text-color-muted);
395
+
+}
396
+
+.post-info a:hover, .comment-info a:hover {
397
+
+ text-decoration: underline;
398
+
+}
399
+
+
400
+
.timeline, .comments {
401
+
display: flex;
402
+
flex-direction: column;
403
+
gap: 1rem;
404
+
+ padding-bottom: 1rem;
405
+
}
406
+
407
+
.login-input-title {
408
+
@@ -182,3 +216,18 @@ select {
409
+
.code-line-content {
410
+
color: var(--text-color);
411
+
}
412
+
+
413
+
+.header, .footer {
414
+
+ color: var(--text-color);
415
+
+}
416
+
+
417
+
+.header a, .header a:visited,
418
+
+.footer a, .footer a:visited {
419
+
+ color: var(--link-color);
420
+
+ text-decoration: none;
421
+
+}
422
+
+
423
+
+.header a:hover,
424
+
+.footer a:hover {
425
+
+ text-decoration: underline;
426
+
+}
427
+
diff --git a/src/views/paste.pug b/src/views/paste.pug
428
+
index 653c02e..3014107 100644
429
+
--- a/src/views/paste.pug
430
+
+++ b/src/views/paste.pug
431
+
@@ -10,13 +10,13 @@ html
432
+
main#content
433
+
+header(ownDid, didHandleMap)
434
+
h1 #{paste.title}
435
+
- p
436
+
+ p.post-info
437
+
| @#{didHandleMap[paste.authorDid]} ·
438
+
| #{timeDifference(now, Date.parse(paste.createdAt))} ago ·
439
+
| #{paste.lang} ·
440
+
| #{paste.code.split('\n').length} loc ·
441
+
a(href=`/r/${paste.shortUrl}`) raw
442
+
- | ·
443
+
+ | ·
444
+
| #{comments.length} #{pluralize(comments.length, 'comment')}
445
+
pre
446
+
code
447
+
@@ -34,13 +34,12 @@ html
448
+
div.comments
449
+
each comment in comments
450
+
div.comment(id=`${encodeURIComponent(comment.uri)}`)
451
+
- p
452
+
+ p.comment-info
453
+
a(href=`/u/${comment.authorDid}`)
454
+
| @#{didHandleMap[comment.authorDid]}
455
+
| ·
456
+
| #{timeDifference(now, Date.parse(paste.createdAt))} ago
457
+
- p
458
+
- pre.comment-body #{comment.body}
459
+
+ pre.comment-body #{comment.body}
460
+
461
+
if ownDid
462
+
form(action=`/${encodeURIComponent(paste.uri)}/comment` method="post").post-form
463
+
--
464
+
2.47.0
465
+