atproto pastebin service: https://plonk.li

add footer, comments, linenrs etc

Changed files
+87 -14
src
+9
src/mixins/footer.pug
···
··· 1 + mixin footer() 2 + hr 3 + div.footer 4 + div.left-side 5 + div.right-side 6 + p 7 + | made by 8 + a(href="https://bsky.app/profile/oppi.li") @oppi.li 9 +
+2 -1
src/mixins/post.pug
··· 13 | #{paste.lang} 14 | · 15 | #{paste.code.split('\n').length} loc 16 -
··· 13 | #{paste.lang} 14 | · 15 | #{paste.code.split('\n').length} loc 16 + | ·  17 + a(href=`/p/${paste.shortUrl}/#comments`) #{paste.commentCount} #{pluralize(paste.commentCount, 'comment')}
+4
src/mixins/utils.pug
··· 2 function randInt(min, max) { 3 return Math.floor(Math.random() * (max - min + 1)) + min; 4 } 5 - 6 function timeDifference(current, previous) { 7 if (!current || !previous) {
··· 2 function randInt(min, max) { 3 return Math.floor(Math.random() * (max - min + 1)) + min; 4 } 5 + - 6 + function pluralize(count, noun) { 7 + return count==1?noun:`${noun}s`; 8 + } 9 - 10 function timeDifference(current, previous) { 11 if (!current || !previous) {
+19 -2
src/public/styles.css
··· 104 hr { 105 border: none; 106 border-top: 1px solid var(--bg-color-muted); 107 - padding: 1rem; 108 } 109 110 .post-form { ··· 152 flex: 1 153 } 154 155 - .header { 156 display: flex; 157 flex-direction: row; 158 justify-content: space-between; ··· 165 text-indent: 1px; 166 text-overflow: ''; 167 }
··· 104 hr { 105 border: none; 106 border-top: 1px solid var(--bg-color-muted); 107 } 108 109 .post-form { ··· 151 flex: 1 152 } 153 154 + .header, .footer { 155 display: flex; 156 flex-direction: row; 157 justify-content: space-between; ··· 164 text-indent: 1px; 165 text-overflow: ''; 166 } 167 + 168 + .code-line { 169 + display: flex; 170 + } 171 + 172 + .code-line-num { 173 + white-space: pre; 174 + -webkit-user-select: none; 175 + user-select: none; 176 + margin-right: 0.4em; 177 + padding: 0 0.4em 0 0.4em; 178 + color: var(--text-color-muted); 179 + text-align: right; 180 + } 181 + 182 + .code-line-content { 183 + color: var(--text-color); 184 + }
+29 -4
src/routes.ts
··· 105 const agent = await getSessionAgent(req, res, ctx); 106 const pastes = await ctx.db 107 .selectFrom("paste") 108 - .selectAll() 109 - .orderBy("indexedAt", "desc") 110 .limit(25) 111 .execute(); 112 ··· 130 const { authorDid } = req.params; 131 const pastes = await ctx.db 132 .selectFrom("paste") 133 - .selectAll() 134 - .where("authorDid", "=", authorDid) 135 .execute(); 136 let didHandleMap: Record<string, string> = {}; 137 didHandleMap[authorDid] = await ctx.resolver.resolveDidToHandle(authorDid);
··· 105 const agent = await getSessionAgent(req, res, ctx); 106 const pastes = await ctx.db 107 .selectFrom("paste") 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") 122 .limit(25) 123 .execute(); 124 ··· 142 const { authorDid } = req.params; 143 const pastes = await ctx.db 144 .selectFrom("paste") 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") 160 .execute(); 161 let didHandleMap: Record<string, string> = {}; 162 didHandleMap[authorDid] = await ctx.resolver.resolveDidToHandle(authorDid);
+3
src/views/index.pug
··· 1 include ../mixins/mkPost 2 include ../mixins/head 3 include ../mixins/header 4 include ../mixins/utils 5 include ../mixins/post 6 ··· 19 "c", 20 "c#", 21 "c++", 22 ].toSorted()) 23 doctype html 24 html ··· 34 each paste in pastes 35 - var handle = didHandleMap[paste.authorDid] 36 +post(paste, handle, paste.authorDid)
··· 1 include ../mixins/mkPost 2 include ../mixins/head 3 include ../mixins/header 4 + include ../mixins/footer 5 include ../mixins/utils 6 include ../mixins/post 7 ··· 20 "c", 21 "c#", 22 "c++", 23 + "cobol", 24 ].toSorted()) 25 doctype html 26 html ··· 36 each paste in pastes 37 - var handle = didHandleMap[paste.authorDid] 38 +post(paste, handle, paste.authorDid) 39 + +footer()
+21 -7
src/views/paste.pug
··· 15 | #{paste.lang} · 16 | #{paste.code.split('\n').length} loc · 17 a(href=`/r/${paste.shortUrl}`) raw 18 pre 19 - | #{paste.code} 20 hr 21 22 if comments.length != 0 23 - h1 comments 24 div.comments 25 each comment in comments 26 div.comment(id=`${encodeURIComponent(comment.uri)}`) ··· 33 pre.comment-body #{comment.body} 34 hr 35 36 - form(action=`/${encodeURIComponent(paste.uri)}/comment` method="post").post-form 37 - div.post-row 38 - textarea#code(name="comment" rows="5" placeholder="add a comment" required).post-input-code 39 40 - div.post-submit-row 41 - button(type="submit").post-input-submit zonk!
··· 15 | #{paste.lang} · 16 | #{paste.code.split('\n').length} loc · 17 a(href=`/r/${paste.shortUrl}`) raw 18 + | &nbsp;·&nbsp; 19 + | #{comments.length} #{pluralize(comments.length, 'comment')} 20 pre 21 + code 22 + - var lines = paste.code.split(/\r?\n|\r|\n/g) 23 + - var tot_chars = lines.length.toString().length 24 + each line, idx in lines 25 + span.code-line 26 + span.code-line-num(id=`L${idx + 1}` style=`min-width: ${tot_chars}ch;`) 27 + | #{idx + 1} 28 + span.code-line-content #{line} 29 hr 30 31 if comments.length != 0 32 + h1(id="comments") comments 33 div.comments 34 each comment in comments 35 div.comment(id=`${encodeURIComponent(comment.uri)}`) ··· 42 pre.comment-body #{comment.body} 43 hr 44 45 + if ownDid 46 + form(action=`/${encodeURIComponent(paste.uri)}/comment` method="post").post-form 47 + div.post-row 48 + textarea#code(name="comment" rows="5" placeholder="add a comment" required).post-input-code 49 50 + div.post-submit-row 51 + button(type="submit").post-input-submit zonk! 52 + else 53 + p 54 + a(href="/login") login 55 + |&nbsp;to post a comment