diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/mixins/comment.pug | 49 | ||||
-rw-r--r-- | src/mixins/post.pug | 8 | ||||
-rw-r--r-- | src/public/styles.css | 85 | ||||
-rw-r--r-- | src/routes/index.js | 11 | ||||
-rw-r--r-- | src/utils.pug | 8 | ||||
-rw-r--r-- | src/views/comments.pug | 9 | ||||
-rw-r--r-- | src/views/index.pug | 36 |
7 files changed, 151 insertions, 55 deletions
diff --git a/src/mixins/comment.pug b/src/mixins/comment.pug index 2ec076f..3af1f53 100644 --- a/src/mixins/comment.pug +++ b/src/mixins/comment.pug | |||
@@ -1,24 +1,41 @@ | |||
1 | include ../utils | 1 | include ../utils |
2 | |||
3 | mixin infoContainer(data) | ||
4 | div.comment-info-container | ||
5 | div.info-item #{fmtnum(data.ups)} ↑ | ||
6 | div.info-item u/#{data.author} #{data.is_submitter ? '(OP)' : ''} | ||
7 | if data.collapsed_reason_code == "DELETED" | ||
8 | div.info-item | ||
9 | a(href=`https://undelete.pullpush.io${data.permalink}`) search on undelete | ||
10 | div.info-item #{timeDifference(Date.now(), data.created * 1000)} | ||
11 | |||
12 | - | ||
13 | function hasReplies(data) { | ||
14 | return data.replies && data.replies.data && data.replies.data.children && data.replies.data.children.length > 0; | ||
15 | } | ||
16 | |||
2 | mixin comment(com, isfirst) | 17 | mixin comment(com, isfirst) |
3 | - var data = com.data | 18 | - var data = com.data |
4 | - var kind = com.kind | 19 | - var kind = com.kind |
20 | - var hasReplyData = hasReplies(data) | ||
21 | |||
5 | if kind == "more" | 22 | if kind == "more" |
6 | div(class=`${isfirst?'first':''}`) | 23 | div(class=`${isfirst ? 'first' : ''}`) |
7 | div.more #{data.count} more comments | 24 | div.more #{data.count} more comments |
8 | else | 25 | else |
9 | div(class=`comment ${isfirst?'first':''}`) | 26 | div(class=`comment ${isfirst ? 'first' : ''}`) |
10 | div.comment-info-container | 27 | if hasReplyData |
11 | div.info-item #{fmtnum(data.ups)} ↑ | 28 | details(id=`${data.id}` open="") |
12 | div.info-item u/#{data.author} #{data.is_submitter?'(OP)':''} | 29 | summary.expand-comments |
13 | if data.collapsed_reason_code == "DELETED" | 30 | +infoContainer(data) |
14 | div.info-item | 31 | div.comment-body |
15 | a(href=`https://undelete.pullpush.io${data.permalink}`) search on undelete | 32 | != data.body_html |
16 | div.info-item #{timeDifference(Date.now(), data.created * 1000)} | 33 | |
17 | div.comment-body | 34 | div.replies |
18 | != data.body_html | ||
19 | div.replies | ||
20 | if data.replies | ||
21 | if data.replies.data | ||
22 | if data.replies.data.children | ||
23 | each reply in data.replies.data.children | 35 | each reply in data.replies.data.children |
24 | +comment(reply,false) | 36 | +comment(reply, false) |
37 | |||
38 | else | ||
39 | +infoContainer(data) | ||
40 | div.comment-body | ||
41 | != data.body_html | ||
diff --git a/src/mixins/post.pug b/src/mixins/post.pug index 287c422..23eb19f 100644 --- a/src/mixins/post.pug +++ b/src/mixins/post.pug | |||
@@ -40,7 +40,7 @@ mixin post(p) | |||
40 | if p.gallery_data | 40 | if p.gallery_data |
41 | if p.gallery_data.items | 41 | if p.gallery_data.items |
42 | details(id=`${p.id}`) | 42 | details(id=`${p.id}`) |
43 | summary expand gallery | 43 | summary.expand-post expand gallery |
44 | div.gallery | 44 | div.gallery |
45 | - var total = p.gallery_data.items.length | 45 | - var total = p.gallery_data.items.length |
46 | - var idx = 0 | 46 | - var idx = 0 |
@@ -58,19 +58,19 @@ mixin post(p) | |||
58 | button(onclick=`toggleDetails('${p.id}')`) close | 58 | button(onclick=`toggleDetails('${p.id}')`) close |
59 | if p.post_hint == "image" && p.thumbnail && p.thumbnail != "self" && p.thumbnail != "default" | 59 | if p.post_hint == "image" && p.thumbnail && p.thumbnail != "self" && p.thumbnail != "default" |
60 | details(id=`${p.id}`) | 60 | details(id=`${p.id}`) |
61 | summary expand image | 61 | summary.expand-post expand image |
62 | a(href=`/media/${p.url}`) | 62 | a(href=`/media/${p.url}`) |
63 | img(src=p.url loading="lazy").post-media | 63 | img(src=p.url loading="lazy").post-media |
64 | button(onclick=`toggleDetails('${p.id}')`) close | 64 | button(onclick=`toggleDetails('${p.id}')`) close |
65 | else if p.post_hint == "hosted:video" | 65 | else if p.post_hint == "hosted:video" |
66 | details(id=`${p.id}`) | 66 | details(id=`${p.id}`) |
67 | summary expand video | 67 | summary.expand-post expand video |
68 | - var url = p.secure_media.reddit_video.dash_url | 68 | - var url = p.secure_media.reddit_video.dash_url |
69 | video(src=url controls data-dashjs-player loading="lazy").post-media | 69 | video(src=url controls data-dashjs-player loading="lazy").post-media |
70 | button(onclick=`toggleDetails('${p.id}')`) close | 70 | button(onclick=`toggleDetails('${p.id}')`) close |
71 | else if !p.post_hint || (p.post_hint == "link" && p.thumbnail && p.thumbnail != "self" && p.thumbnail != "default") | 71 | else if !p.post_hint || (p.post_hint == "link" && p.thumbnail && p.thumbnail != "self" && p.thumbnail != "default") |
72 | details(id=`${p.id}`) | 72 | details(id=`${p.id}`) |
73 | summary expand link | 73 | summary.expand-post expand link |
74 | a(href=`${p.url}`) | 74 | a(href=`${p.url}`) |
75 | | #{p.url} | 75 | | #{p.url} |
76 | br | 76 | br |
diff --git a/src/public/styles.css b/src/public/styles.css index 4dc2740..76f70b5 100644 --- a/src/public/styles.css +++ b/src/public/styles.css | |||
@@ -1,4 +1,4 @@ | |||
1 | @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap'); | 1 | @import url('https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&display=swap'); |
2 | 2 | ||
3 | :root { | 3 | :root { |
4 | /* Light mode colors */ | 4 | /* Light mode colors */ |
@@ -17,7 +17,7 @@ | |||
17 | --bg-color-muted: #333; | 17 | --bg-color-muted: #333; |
18 | --text-color: white; | 18 | --text-color: white; |
19 | --text-color-muted: #999; | 19 | --text-color-muted: #999; |
20 | --blockquote-color: green; | 20 | --blockquote-color: lightgreen; |
21 | --link-color: lightblue; | 21 | --link-color: lightblue; |
22 | --link-visited-color: violet; | 22 | --link-visited-color: violet; |
23 | } | 23 | } |
@@ -58,6 +58,27 @@ a:visited { | |||
58 | justify-content: center; | 58 | justify-content: center; |
59 | } | 59 | } |
60 | 60 | ||
61 | .sub-title { | ||
62 | display: flex; | ||
63 | } | ||
64 | |||
65 | #button-container { | ||
66 | margin-left: 10px; | ||
67 | display: flex; | ||
68 | align-items: center; | ||
69 | } | ||
70 | |||
71 | .sort-opts { | ||
72 | display: flex; | ||
73 | flex-direction: row; | ||
74 | flex-wrap: wrap; | ||
75 | justify-content: space-between; | ||
76 | } | ||
77 | |||
78 | .sort-opts a { | ||
79 | margin: 10px; | ||
80 | } | ||
81 | |||
61 | .footer { | 82 | .footer { |
62 | display: flex; | 83 | display: flex; |
63 | flex-direction: row; | 84 | flex-direction: row; |
@@ -90,15 +111,22 @@ nav { | |||
90 | .info-container, | 111 | .info-container, |
91 | .comment-info-container, | 112 | .comment-info-container, |
92 | .more, | 113 | .more, |
114 | summary.expand-comments::before, | ||
93 | hr { | 115 | hr { |
94 | color: var(--text-color-muted) | 116 | color: var(--text-color-muted) |
95 | } | 117 | } |
96 | 118 | ||
97 | .info-container, .comment-info-container, .more { | 119 | .info-container, .more { |
98 | font-size: 0.8rem; | 120 | font-size: 0.8rem; |
99 | display: flex; | 121 | display: flex; |
100 | } | 122 | } |
101 | 123 | ||
124 | .comment-info-container { | ||
125 | display: inline-flex; | ||
126 | align-items: center; | ||
127 | font-size: 0.8rem; | ||
128 | } | ||
129 | |||
102 | .domain { | 130 | .domain { |
103 | color: var(--text-color-muted); | 131 | color: var(--text-color-muted); |
104 | font-size: 0.8rem; | 132 | font-size: 0.8rem; |
@@ -124,6 +152,13 @@ hr { | |||
124 | display: none | 152 | display: none |
125 | } | 153 | } |
126 | 154 | ||
155 | .post-media { | ||
156 | display: block; | ||
157 | margin: 0 auto; | ||
158 | max-width: 95%; | ||
159 | padding: 5px; | ||
160 | } | ||
161 | |||
127 | @media (min-width: 768px) { | 162 | @media (min-width: 768px) { |
128 | .post, .comments-container, .hero, .header, .footer { | 163 | .post, .comments-container, .hero, .header, .footer { |
129 | flex: 1 1 90%; | 164 | flex: 1 1 90%; |
@@ -135,7 +170,8 @@ hr { | |||
135 | .comments-container { | 170 | .comments-container { |
136 | font-size: 1.3rem; | 171 | font-size: 1.3rem; |
137 | } | 172 | } |
138 | .info-container, .comment-info-container, .more { | 173 | .info-container, .comment-info-container, .more, summary.expand-comments::before |
174 | { | ||
139 | font-size: 1rem; | 175 | font-size: 1rem; |
140 | } | 176 | } |
141 | .domain { | 177 | .domain { |
@@ -150,6 +186,9 @@ hr { | |||
150 | .post-author { | 186 | .post-author { |
151 | display: inline | 187 | display: inline |
152 | } | 188 | } |
189 | .post-media { | ||
190 | max-width: 50%; | ||
191 | } | ||
153 | } | 192 | } |
154 | 193 | ||
155 | @media (min-width: 1080px) { | 194 | @media (min-width: 1080px) { |
@@ -163,7 +202,7 @@ hr { | |||
163 | .comments-container { | 202 | .comments-container { |
164 | font-size: 1.3rem; | 203 | font-size: 1.3rem; |
165 | } | 204 | } |
166 | .info-container, .comment-info-container, .more { | 205 | .info-container, .comment-info-container, .more, summary.expand-comments::before { |
167 | font-size: 1rem; | 206 | font-size: 1rem; |
168 | } | 207 | } |
169 | .domain { | 208 | .domain { |
@@ -178,6 +217,9 @@ hr { | |||
178 | .post-author { | 217 | .post-author { |
179 | display: inline | 218 | display: inline |
180 | } | 219 | } |
220 | .post-media { | ||
221 | max-width: 50%; | ||
222 | } | ||
181 | } | 223 | } |
182 | 224 | ||
183 | .comments-container, .self-text { | 225 | .comments-container, .self-text { |
@@ -229,15 +271,7 @@ hr { | |||
229 | flex-direction: row; | 271 | flex-direction: row; |
230 | } | 272 | } |
231 | 273 | ||
232 | .post-media { | 274 | .title-container, .comment-info-container, summary.expand-comments::before { |
233 | display: block; | ||
234 | margin: 0 auto; | ||
235 | max-width: 95%; | ||
236 | padding: 5px; | ||
237 | } | ||
238 | |||
239 | .title-container, .comment-info-container { | ||
240 | flex: 1; | ||
241 | margin-top: 10px; | 275 | margin-top: 10px; |
242 | margin-bottom: 10px; | 276 | margin-bottom: 10px; |
243 | } | 277 | } |
@@ -296,10 +330,31 @@ p { | |||
296 | text-align: left; | 330 | text-align: left; |
297 | } | 331 | } |
298 | 332 | ||
299 | summary { | 333 | summary.expand-post { |
300 | display: none; | 334 | display: none; |
301 | } | 335 | } |
302 | 336 | ||
337 | summary.expand-comments { | ||
338 | list-style: none; | ||
339 | cursor: pointer; | ||
340 | } | ||
341 | |||
342 | summary.expand-comments::before { | ||
343 | content: "[+] "; | ||
344 | } | ||
345 | |||
346 | details[open] summary.expand-comments::before { | ||
347 | content: "[-] "; | ||
348 | } | ||
349 | |||
350 | details:not([open]) summary.expand-comments::before { | ||
351 | content: "[+] "; | ||
352 | } | ||
353 | |||
354 | .comment-body { | ||
355 | display: block; | ||
356 | } | ||
357 | |||
303 | .footer { | 358 | .footer { |
304 | padding-bottom: 40px; | 359 | padding-bottom: 40px; |
305 | } | 360 | } |
diff --git a/src/routes/index.js b/src/routes/index.js index cef05da..f7a0425 100644 --- a/src/routes/index.js +++ b/src/routes/index.js | |||
@@ -11,18 +11,17 @@ router.get('/', async (req, res) => { | |||
11 | }); | 11 | }); |
12 | 12 | ||
13 | // GET /r/:id | 13 | // GET /r/:id |
14 | router.get('/r/:subreddit/:sort?', async (req, res) => { | 14 | router.get('/r/:subreddit', async (req, res) => { |
15 | var subreddit = req.params.subreddit; | 15 | var subreddit = req.params.subreddit; |
16 | var query = req.query; | 16 | var query = req.query? req.query : {}; |
17 | var sort = req.params.sort ? req.params.sort : 'hot'; | 17 | var sort = query.sort? query.sort : 'hot'; |
18 | var options = req.query; | ||
19 | 18 | ||
20 | var postsReq = G.getSubmissions(sort, `${subreddit}`, options); | 19 | var postsReq = G.getSubmissions(sort, `${subreddit}`, query); |
21 | var aboutReq = G.getSubreddit(`${subreddit}`); | 20 | var aboutReq = G.getSubreddit(`${subreddit}`); |
22 | 21 | ||
23 | var [posts, about] = await Promise.all([postsReq, aboutReq]); | 22 | var [posts, about] = await Promise.all([postsReq, aboutReq]); |
24 | 23 | ||
25 | res.render('index', { subreddit, posts, about }); | 24 | res.render('index', { subreddit, posts, about, query }); |
26 | }); | 25 | }); |
27 | 26 | ||
28 | // GET /comments/:id | 27 | // GET /comments/:id |
diff --git a/src/utils.pug b/src/utils.pug index 81cf3f7..17d1763 100644 --- a/src/utils.pug +++ b/src/utils.pug | |||
@@ -15,7 +15,7 @@ | |||
15 | if (elapsed < msPerMinute) { | 15 | if (elapsed < msPerMinute) { |
16 | return Math.round(elapsed/1000) + 's'; | 16 | return Math.round(elapsed/1000) + 's'; |
17 | } else if (elapsed < msPerHour) { | 17 | } else if (elapsed < msPerHour) { |
18 | return Math.round(elapsed/msPerMinute) + 'min'; | 18 | return Math.round(elapsed/msPerMinute) + 'm'; |
19 | } else if (elapsed < msPerDay ) { | 19 | } else if (elapsed < msPerDay ) { |
20 | return Math.round(elapsed/msPerHour ) + 'h'; | 20 | return Math.round(elapsed/msPerHour ) + 'h'; |
21 | } else if (elapsed < msPerMonth) { | 21 | } else if (elapsed < msPerMonth) { |
@@ -26,3 +26,9 @@ | |||
26 | return Math.round(elapsed/msPerYear ) + 'y'; | 26 | return Math.round(elapsed/msPerYear ) + 'y'; |
27 | } | 27 | } |
28 | } | 28 | } |
29 | - | ||
30 | function encodeQueryParams(obj) { | ||
31 | return Object.keys(obj) | ||
32 | .map(key => encodeURIComponent(key) + '=' + encodeURIComponent(obj[key])) | ||
33 | .join('&'); | ||
34 | } | ||
diff --git a/src/views/comments.pug b/src/views/comments.pug index 8d5acf3..d9c96e9 100644 --- a/src/views/comments.pug +++ b/src/views/comments.pug | |||
@@ -1,5 +1,6 @@ | |||
1 | include ../mixins/comment | 1 | include ../mixins/comment |
2 | include ../mixins/header | 2 | include ../mixins/header |
3 | include ../utils | ||
3 | 4 | ||
4 | doctype html | 5 | doctype html |
5 | html | 6 | html |
@@ -9,6 +10,14 @@ html | |||
9 | title reddit | 10 | title reddit |
10 | link(rel='stylesheet', href='/styles.css') | 11 | link(rel='stylesheet', href='/styles.css') |
11 | script(src="https://cdn.dashjs.org/latest/dash.all.min.js") | 12 | script(src="https://cdn.dashjs.org/latest/dash.all.min.js") |
13 | script. | ||
14 | function toggleDetails(details_id) { | ||
15 | var detailsElement = document.getElementById(details_id); | ||
16 | if (detailsElement) { | ||
17 | detailsElement.open = !detailsElement.open; | ||
18 | } | ||
19 | } | ||
20 | |||
12 | body | 21 | body |
13 | main#content | 22 | main#content |
14 | +header() | 23 | +header() |
diff --git a/src/views/index.pug b/src/views/index.pug index 3f284f3..01b2941 100644 --- a/src/views/index.pug +++ b/src/views/index.pug | |||
@@ -1,6 +1,7 @@ | |||
1 | include ../mixins/post | 1 | include ../mixins/post |
2 | include ../mixins/sub | 2 | include ../mixins/sub |
3 | include ../mixins/header | 3 | include ../mixins/header |
4 | include ../utils | ||
4 | - var subs = [] | 5 | - var subs = [] |
5 | doctype html | 6 | doctype html |
6 | html | 7 | html |
@@ -42,22 +43,31 @@ html | |||
42 | +header() | 43 | +header() |
43 | 44 | ||
44 | div.hero | 45 | div.hero |
45 | a(href=`/r/${subreddit}`) | 46 | div.sub-title |
46 | h1 r/#{subreddit} | 47 | a(href=`/r/${subreddit}`) |
48 | h1 r/#{subreddit} | ||
49 | div#button-container | ||
47 | if about | 50 | if about |
48 | p #{about.public_description} | 51 | p #{about.public_description} |
49 | div#button-container | 52 | details |
50 | ul | 53 | summary sort by |
51 | li | 54 | div.sort-opts |
52 | a(href=`/r/${subreddit}/hot`) hot | 55 | a(href=`/r/${subreddit}?sort=hot`) hot |
53 | li | 56 | a(href=`/r/${subreddit}?sort=new`) new |
54 | a(href=`/r/${subreddit}/top`) top | 57 | a(href=`/r/${subreddit}?sort=rising`) rising |
55 | li | 58 | a(href=`/r/${subreddit}?sort=top`) top |
56 | a(href=`/r/${subreddit}/top?t=all`) top all | 59 | a(href=`/r/${subreddit}?sort=top&t=day`) top day |
60 | a(href=`/r/${subreddit}?sort=top&t=week`) top week | ||
61 | a(href=`/r/${subreddit}?sort=top&t=month`) top month | ||
62 | a(href=`/r/${subreddit}?sort=top&t=year`) top year | ||
63 | a(href=`/r/${subreddit}?sort=top&t=all`) top all | ||
57 | 64 | ||
58 | if posts | 65 | if posts |
59 | each child in posts.posts | 66 | each child in posts.posts |
60 | +post(child.data) | 67 | +post(child.data) |
61 | div.footer | 68 | |
62 | div.footer-item | 69 | if posts.after |
63 | a(href=`/r/${subreddit}?after=${posts.after}`) next → | 70 | div.footer |
71 | div.footer-item | ||
72 | - var newQuery = {...query, after: posts.after} | ||
73 | a(href=`/r/${subreddit}?${encodeQueryParams(newQuery)}`) next → | ||