diff options
author | PortableProgrammer <[email protected]> | 2025-01-10 20:37:49 +0000 |
---|---|---|
committer | PortableProgrammer <[email protected]> | 2025-01-10 20:37:49 +0000 |
commit | 83ab88264880b13e2d0826ee0af8a6f17b18c33e (patch) | |
tree | 925f2c2991605527acc1e3282bc8e9fa9602ded1 | |
parent | f983c1313cd17fc5acf5f703638ec53e15c831bf (diff) |
Feat: Consolidate/port Card and Compact media viewers
-rw-r--r-- | src/mixins/post.pug | 93 | ||||
-rw-r--r-- | src/public/styles.css | 70 |
2 files changed, 69 insertions, 94 deletions
diff --git a/src/mixins/post.pug b/src/mixins/post.pug index c4f3bc5..30310a8 100644 --- a/src/mixins/post.pug +++ b/src/mixins/post.pug | |||
@@ -28,77 +28,58 @@ mixin post(p, currentUrl) | |||
28 | | · | 28 | | · |
29 | a(href=`/comments/${p.id}?from=${from}&sort=${sortQuery}&view=${viewQuery}`) #{fmtnum (p.num_comments)} ↩ | 29 | a(href=`/comments/${p.id}?from=${from}&sort=${sortQuery}&view=${viewQuery}`) #{fmtnum (p.num_comments)} ↩ |
30 | if (query.view == "card" && !isPostGallery(p) && !isPostImage(p) && !isPostVideo(p) && p.selftext_html) | 30 | if (query.view == "card" && !isPostGallery(p) && !isPostImage(p) && !isPostVideo(p) && p.selftext_html) |
31 | div.self-text-overflow(class='card') | 31 | div.self-text-overflow.card |
32 | if query.view == "card" && (p.spoiler || p.over_18) | 32 | if p.spoiler || p.over_18 |
33 | div.spoiler(id=`spoiler_${p.id}`, onclick=`javascript:document.getElementById('spoiler_${p.id}').style.display = 'none';`) | 33 | div.spoiler(id=`spoiler_${p.id}`, onclick=`javascript:document.getElementById('spoiler_${p.id}').style.display = 'none';`) |
34 | h2 | 34 | h2 |
35 | != p.over_18 ? 'nsfw' : 'spoiler' | 35 | != p.over_18 ? 'nsfw' : 'spoiler' |
36 | div.self-text(class='card') | 36 | div.self-text.card |
37 | != convertInlineImageLinks(p.selftext_html) | 37 | != convertInlineImageLinks(p.selftext_html) |
38 | div.media-preview(class=`${query.view}`) | 38 | if query.view != "card" |
39 | - var onclick = query.view != "card" ? `toggleDetails('${p.id}')` : `` | 39 | div.media-preview |
40 | - var onclick = `toggleDetails('${p.id}')` | ||
41 | if isPostGallery(p) | ||
42 | - var item = (p.over_18 ? `/nsfw.svg` : p.spoiler ? `/spoiler.svg` : postGalleryItems(p)[0].url) | ||
43 | img(src=item onclick=onclick) | ||
44 | else if isPostImage(p) | ||
45 | - var url = postThumbnail(p) | ||
46 | img(src=url onclick=onclick) | ||
47 | else if isPostVideo(p) | ||
48 | - var decodedVideos = decodePostVideoUrls(p) | ||
49 | video(autoplay="" muted="" data-dashjs-player="" onclick=`toggleDetails('${p.id}')` poster=decodedVideos[4] width="100px" height="100px") | ||
50 | // Scrubber | ||
51 | source(src=decodedVideos[3]) | ||
52 | else if isPostLink(p) | ||
53 | a(href=p.url) | ||
54 | | ↗ | ||
55 | |||
56 | details(id=`${p.id}` open=(query.view == "card" && (isPostGallery(p) || isPostImage(p) || isPostVideo(p)))) | ||
57 | summary.expand-post expand media | ||
58 | div.image-viewer | ||
40 | if query.view == "card" && (p.spoiler || p.over_18) && (isPostGallery(p) || isPostImage(p) || isPostVideo(p)) | 59 | if query.view == "card" && (p.spoiler || p.over_18) && (isPostGallery(p) || isPostImage(p) || isPostVideo(p)) |
41 | div.spoiler(id=`spoiler_${p.id}`, onclick=`javascript:document.getElementById('spoiler_${p.id}').style.display = 'none';`) | 60 | div.spoiler(id=`spoiler_${p.id}`, onclick=`javascript:document.getElementById('spoiler_${p.id}').style.display = 'none';`) |
42 | h2 | 61 | h2 |
43 | != p.over_18 ? 'nsfw' : 'spoiler' | 62 | != p.over_18 ? 'nsfw' : 'spoiler' |
44 | if isPostGallery(p) | 63 | if isPostGallery(p) |
45 | - var item = postGalleryItems(p)[0] | 64 | div.gallery |
46 | if query.view == "card" | 65 | each item in postGalleryItems(p) |
47 | div.gallery(class=`${query.view}`) | 66 | div.gallery-item |
48 | each item in postGalleryItems(p) | 67 | a(href=`/media/${item.url}`) |
49 | div.gallery-item(class=`${query.view}`) | 68 | img(src=item.url loading="lazy") |
50 | a(href=`/media/${item.url}`) | 69 | div.gallery-item-idx |
51 | img(src=item.url loading="lazy") | 70 | | #{`${item.idx}/${item.total}`} |
52 | div.gallery-item-idx(class=`${query.view}`) | ||
53 | | #{`${item.idx}/${item.total}`} | ||
54 | else | ||
55 | img(src=item.url onclick=onclick) | ||
56 | else if isPostImage(p) | 71 | else if isPostImage(p) |
57 | - var url = query.view == "card" ? p.url : postThumbnail(p) | 72 | a(href=`/media/${p.url}`) |
58 | #{query.view == "card" ? "a href=/media/" + url : span} | 73 | img(src=p.url loading="lazy") |
59 | img(src=url onclick=onclick) | ||
60 | else if isPostVideo(p) | 74 | else if isPostVideo(p) |
61 | - var decodedVideos = decodePostVideoUrls(p) | 75 | - var decodedVideos = decodePostVideoUrls(p) |
62 | if query.view == "card" | 76 | video(controls="" muted="" data-dashjs-player="" preload="metadata" playsinline="" poster=decodedVideos[4] objectfit="contain" loading="lazy") |
63 | video(controls="" muted="" data-dashjs-player="" preload="metadata" poster=decodedVideos[4]) | ||
64 | // HLS | 77 | // HLS |
65 | source(src=decodedVideos[0]) | 78 | source(src=decodedVideos[0]) |
66 | // Dash | 79 | // Dash |
67 | source(src=decodedVideos[1]) | 80 | source(src=decodedVideos[1]) |
68 | // Fallback | 81 | // Fallback |
69 | source(src=decodedVideos[2]) | 82 | source(src=decodedVideos[2]) |
70 | else | 83 | if (query.view == "compact") |
71 | video(autoplay="" muted="" data-dashjs-player="" onclick=`toggleDetails('${p.id}')` width="100px" height="100px") | 84 | button(onclick=`toggleDetails('${p.id}')`) |
72 | // Scrubber | 85 | | close |
73 | source(src=decodedVideos[3]) | ||
74 | else if isPostLink(p) | ||
75 | a(href=p.url) | ||
76 | if (query.view == 'card') | ||
77 | | #{p.domain} | ||
78 | | ↗ | ||
79 | |||
80 | if query.view == "compact" && (isPostGallery(p) || isPostImage(p) || isPostVideo(p)) | ||
81 | details(id=`${p.id}`) | ||
82 | summary.expand-post expand media | ||
83 | div.image-viewer | ||
84 | if isPostGallery(p) | ||
85 | div.gallery | ||
86 | each item in postGalleryItems(p) | ||
87 | div.gallery-item | ||
88 | div.gallery-item-idx | ||
89 | | #{`${item.idx}/${item.total}`} | ||
90 | a(href=`/media/${item.url}`) | ||
91 | img(src=item.url loading="lazy") | ||
92 | else if isPostImage(p) | ||
93 | a(href=`/media/${p.url}`) | ||
94 | img(src=p.url loading="lazy").post-media | ||
95 | else if isPostVideo(p) | ||
96 | video(controls="" muted="" data-dashjs-player="" preload="metadata" playsinline="" poster=decodedVideos[4] objectfit="contain" loading="lazy").post-media | ||
97 | //HLS | ||
98 | source(src=decodedVideos[0]) | ||
99 | // Dash | ||
100 | source(src=decodedVideos[1]) | ||
101 | // Fallback | ||
102 | source(src=decodedVideos[2]) | ||
103 | button(onclick=`toggleDetails('${p.id}')`) | ||
104 | | close | ||
diff --git a/src/public/styles.css b/src/public/styles.css index d9f6a40..8bfdc72 100644 --- a/src/public/styles.css +++ b/src/public/styles.css | |||
@@ -11,6 +11,9 @@ | |||
11 | --link-visited-color: #999; | 11 | --link-visited-color: #999; |
12 | --accent: var(--link-color); | 12 | --accent: var(--link-color); |
13 | --error-text-color: red; | 13 | --error-text-color: red; |
14 | --border-radius-card: 8px; | ||
15 | --border-radius-media: 6px; | ||
16 | --border-radius-preview: 4px; | ||
14 | 17 | ||
15 | font-family: Inter, sans-serif; | 18 | font-family: Inter, sans-serif; |
16 | font-feature-settings: 'ss01' 1, 'kern' 1, 'liga' 1, 'cv05' 1, 'dlig' 1, 'ss01' 1, 'ss07' 1, 'ss08' 1; | 19 | font-feature-settings: 'ss01' 1, 'kern' 1, 'liga' 1, 'cv05' 1, 'dlig' 1, 'ss01' 1, 'ss07' 1, 'ss08' 1; |
@@ -47,10 +50,6 @@ body { | |||
47 | color: var(--text-color); | 50 | color: var(--text-color); |
48 | } | 51 | } |
49 | 52 | ||
50 | body:has(details.card[open]) { | ||
51 | overflow: hidden; | ||
52 | } | ||
53 | |||
54 | body.media-maximized { | 53 | body.media-maximized { |
55 | /* Fix for Safari User Agent stylesheet */ | 54 | /* Fix for Safari User Agent stylesheet */ |
56 | margin: 0; | 55 | margin: 0; |
@@ -169,7 +168,7 @@ nav { | |||
169 | 168 | ||
170 | .post-container.card { | 169 | .post-container.card { |
171 | border: 1px solid var(--bg-color-muted); | 170 | border: 1px solid var(--bg-color-muted); |
172 | border-radius: 8px; | 171 | border-radius: var(--border-radius-card); |
173 | display: block; | 172 | display: block; |
174 | } | 173 | } |
175 | 174 | ||
@@ -198,37 +197,22 @@ nav { | |||
198 | text-overflow: ellipsis; | 197 | text-overflow: ellipsis; |
199 | } | 198 | } |
200 | 199 | ||
201 | .media-preview.card { | 200 | .image-viewer { |
202 | position: relative; | 201 | position: relative; |
203 | padding: 0.3rem; | 202 | padding: 0.3rem; |
204 | padding-bottom: 0.3rem; | 203 | padding-bottom: 0.3rem; |
205 | } | 204 | } |
206 | 205 | ||
207 | .media-preview.card > img { | 206 | .image-viewer > img { |
208 | cursor: pointer; | 207 | cursor: pointer; |
209 | } | 208 | } |
210 | 209 | ||
211 | .gallery.card { | ||
212 | align-items: center; | ||
213 | scroll-snap-type: both mandatory; | ||
214 | } | ||
215 | |||
216 | .gallery-item.card { | ||
217 | max-width: 100%; | ||
218 | width: 100%; | ||
219 | scroll-snap-align: center; | ||
220 | } | ||
221 | |||
222 | .gallery-item-idx.card { | ||
223 | text-align: center; | ||
224 | } | ||
225 | |||
226 | .spoiler { | 210 | .spoiler { |
227 | background-color: rbga(var(--bg-color-muted), 0.2); | 211 | background-color: rbga(var(--bg-color-muted), 0.2); |
228 | /* Safari on iOS <= 17 */ | 212 | /* Safari on iOS <= 17 */ |
229 | -webkit-backdrop-filter: blur(3rem); | 213 | -webkit-backdrop-filter: blur(3rem); |
230 | backdrop-filter: blur(3rem); | 214 | backdrop-filter: blur(3rem); |
231 | border-radius: 4px; | 215 | border-radius: var(--border-radius-preview); |
232 | 216 | ||
233 | position: absolute; | 217 | position: absolute; |
234 | top: 0; | 218 | top: 0; |
@@ -247,7 +231,7 @@ nav { | |||
247 | z-index: 10; | 231 | z-index: 10; |
248 | } | 232 | } |
249 | 233 | ||
250 | .gallery-item-idx.card, | 234 | .gallery-item-idx, |
251 | .spoiler > h2 { | 235 | .spoiler > h2 { |
252 | text-shadow: 0.1rem 0.1rem 1rem var(--bg-color-muted); | 236 | text-shadow: 0.1rem 0.1rem 1rem var(--bg-color-muted); |
253 | } | 237 | } |
@@ -294,15 +278,16 @@ summary::before { | |||
294 | object-fit: cover; | 278 | object-fit: cover; |
295 | width: 4rem; | 279 | width: 4rem; |
296 | height: 4rem; | 280 | height: 4rem; |
281 | border-radius: var(--border-radius-preview); | ||
297 | } | 282 | } |
298 | 283 | ||
299 | .media-preview.card { | 284 | .image-viewer { |
300 | padding: unset; | 285 | padding: unset; |
301 | } | 286 | } |
302 | 287 | ||
303 | .media-preview.card img, | 288 | .image-viewer img, |
304 | .media-preview.card video { | 289 | .image-viewer video { |
305 | border-radius: 6px; | 290 | border-radius: var(--border-radius-media); |
306 | 291 | ||
307 | max-height: 40vh; | 292 | max-height: 40vh; |
308 | max-width: 95%; | 293 | max-width: 95%; |
@@ -317,13 +302,13 @@ summary::before { | |||
317 | object-fit: fill; | 302 | object-fit: fill; |
318 | } | 303 | } |
319 | 304 | ||
320 | .media-preview.card a { | 305 | .image-viewer a { |
321 | font-size: 1.5rem; | 306 | font-size: 1.5rem; |
322 | padding: unset; | 307 | padding: unset; |
323 | padding-left: 1rem; | 308 | padding-left: 1rem; |
324 | } | 309 | } |
325 | 310 | ||
326 | .media-preview.card a:has(img) { | 311 | .image-viewer a:has(img) { |
327 | font-size: 0rem; | 312 | font-size: 0rem; |
328 | padding: unset; | 313 | padding: unset; |
329 | } | 314 | } |
@@ -382,12 +367,12 @@ form { | |||
382 | width: 5rem; | 367 | width: 5rem; |
383 | height: 5rem; | 368 | height: 5rem; |
384 | } | 369 | } |
385 | .media-preview.card img, | 370 | .image-viewer img, |
386 | .media-preview.card video | 371 | .image-viewer video |
387 | { | 372 | { |
388 | max-height: 50vh; | 373 | max-height: 50vh; |
389 | } | 374 | } |
390 | .media-preview.card a { | 375 | .image-viewer a { |
391 | font-size: 1rem; | 376 | font-size: 1rem; |
392 | margin: 0.7rem; | 377 | margin: 0.7rem; |
393 | padding: initial; | 378 | padding: initial; |
@@ -424,8 +409,8 @@ form { | |||
424 | width: 5rem; | 409 | width: 5rem; |
425 | height: 5rem; | 410 | height: 5rem; |
426 | } | 411 | } |
427 | .media-preview.card img, | 412 | .image-viewer img, |
428 | .media-preview.card video | 413 | .image-viewer video |
429 | { | 414 | { |
430 | max-height: 30vh; | 415 | max-height: 30vh; |
431 | } | 416 | } |
@@ -433,7 +418,7 @@ form { | |||
433 | font-size: 2rem; | 418 | font-size: 2rem; |
434 | padding: 2rem; | 419 | padding: 2rem; |
435 | } | 420 | } |
436 | .media-preview.card a { | 421 | .image-viewer a { |
437 | font-size: 1rem; | 422 | font-size: 1rem; |
438 | margin: 0.5rem; | 423 | margin: 0.5rem; |
439 | padding: initial; | 424 | padding: initial; |
@@ -464,8 +449,8 @@ form { | |||
464 | flex: 1 1 40%; | 449 | flex: 1 1 40%; |
465 | width: 40%; | 450 | width: 40%; |
466 | } | 451 | } |
467 | .media-preview.card img, | 452 | .image-viewer img, |
468 | .media-preview.card video | 453 | .image-viewer video |
469 | { | 454 | { |
470 | max-height: 20vh; | 455 | max-height: 20vh; |
471 | } | 456 | } |
@@ -648,11 +633,20 @@ a { | |||
648 | overflow-x: auto; | 633 | overflow-x: auto; |
649 | position: relative; | 634 | position: relative; |
650 | padding: 5px; | 635 | padding: 5px; |
636 | align-items: center; | ||
637 | scroll-snap-type: both mandatory; | ||
651 | } | 638 | } |
652 | 639 | ||
653 | .gallery-item { | 640 | .gallery-item { |
654 | flex: 0 0 auto; | 641 | flex: 0 0 auto; |
655 | margin-right: 10px; | 642 | margin-right: 10px; |
643 | max-width: 100%; | ||
644 | width: 100%; | ||
645 | scroll-snap-align: center; | ||
646 | } | ||
647 | |||
648 | .gallery-item-idx { | ||
649 | text-align: center; | ||
656 | } | 650 | } |
657 | 651 | ||
658 | .gallery img { | 652 | .gallery img { |