From eae5094ea241cc69b38cce328b73e858e6ff63de Mon Sep 17 00:00:00 2001 From: PortableProgrammer Date: Mon, 30 Dec 2024 21:17:57 +0000 Subject: Feat: Card View Initial Commit --- src/mixins/header.pug | 12 ++-- src/mixins/post.pug | 105 ++++++++++++++++----------- src/mixins/postUtils.pug | 42 +++++++++-- src/public/styles.css | 179 ++++++++++++++++++++++++++++++++++++++++++++++ src/routes/index.js | 43 ++++++++--- src/views/comments.pug | 6 +- src/views/index.pug | 33 +++++---- src/views/post-search.pug | 4 ++ src/views/search.pug | 6 ++ src/views/sub-search.pug | 6 +- src/views/subs.pug | 4 +- 11 files changed, 364 insertions(+), 76 deletions(-) (limited to 'src') diff --git a/src/mixins/header.pug b/src/mixins/header.pug index 9cf1e1a..7d56ff5 100644 --- a/src/mixins/header.pug +++ b/src/mixins/header.pug @@ -1,16 +1,18 @@ mixin header(user) + - var viewQuery = 'view=' + (query && query.view ? query.view : 'compact') + - var sortQuery = 'sort=' + (query ? (query.sort ? query.sort + (query.t ? '&t=' + query.t : '') : 'hot') : 'hot') div.header div.header-item - a(href=`/`) home + a(href=`/?${sortQuery}&${viewQuery}`) home div.header-item - a(href=`/r/all`) all + a(href=`/r/all?${sortQuery}&${viewQuery}`) all div.header-item - a(href=`/search`) search + a(href=`/search?${sortQuery}&${viewQuery}`) search div.header-item - a(href=`/subs`) subs + a(href=`/subs?${sortQuery}&${viewQuery}`) subs if user div.header-item - a(href='/dashboard') #{user.username} + a(href=`/dashboard?${sortQuery}&${viewQuery}`) #{user.username} |  a(href='/logout') (logout) else diff --git a/src/mixins/post.pug b/src/mixins/post.pug index 74a2b78..4022424 100644 --- a/src/mixins/post.pug +++ b/src/mixins/post.pug @@ -2,11 +2,13 @@ include ../utils include postUtils mixin post(p, currentUrl) - var from = encodeURIComponent(currentUrl) + - var viewQuery = query && query.view ? query.view : 'compact' + - var sortQuery = query && query.sort ? query.sort + (query.t ? '&t=' + query.t : '') : 'hot' article.post - div.post-container - div.post-text - div.title-container - a(href=`/comments/${p.id}?from=${from}`) + div.post-container(class=`${query.view}`) + div.post-text(class=`${query.view}`) + div.title-container(class=`${query.view}`) + a(class=`${query.view}`, href=`/comments/${p.id}?from=${from}&sort=${sortQuery}&view=${viewQuery}`) != p.title span.domain (#{p.domain}) div.info-container @@ -18,50 +20,73 @@ mixin post(p, currentUrl) |  ·  | #{timeDifference(Date.now(), p.created * 1000)} |  ·  - a(href=`/r/${p.subreddit}`) r/#{p.subreddit} + a(href=`/r/${p.subreddit}?sort=${sortQuery}&view=${viewQuery}`) r/#{p.subreddit} |  ·  - a(href=`/comments/${p.id}?from=${from}`) #{fmtnum (p.num_comments)} ↩ - div.media-preview + a(href=`/comments/${p.id}?from=${from}&sort=${sortQuery}&view=${viewQuery}`) #{fmtnum (p.num_comments)} ↩ + if (query.view == "card" && !isPostGallery(p) && !isPostImage(p) && !isPostVideo(p) && p.selftext_html) + div.self-text-overflow(class='card') + if query.view == "card" && (p.spoiler || p.over_18) + div.spoiler(id=`spoiler_${p.id}`, onclick=`javascript:document.getElementById('spoiler_${p.id}').style.display = 'none';`) + h2 + != p.over_18 ? 'nsfw' : 'spoiler' + div.self-text(class='card') + != convertInlineImageLinks(p.selftext_html) + div.media-preview(class=`${query.view}`) + if query.view == "card" && (p.spoiler || p.over_18) && (isPostGallery(p) || isPostImage(p) || isPostVideo(p)) + div.spoiler(id=`spoiler_${p.id}`, onclick=`javascript:document.getElementById('spoiler_${p.id}').style.display = 'none';`) + h2 + != p.over_18 ? 'nsfw' : 'spoiler' if isPostGallery(p) - var item = postGalleryItems(p)[0] img(src=item.url onclick=`toggleDetails('${p.id}')`) else if isPostImage(p) - - var url = postThumbnail(p) + - var url = query.view == "card" ? p.url : postThumbnail(p) img(src=url onclick=`toggleDetails('${p.id}')`) else if isPostVideo(p) - - var url = p.secure_media.reddit_video.scrubber_media_url - video(src=url data-dashjs-player width='100px' height='100px' onclick=`toggleDetails('${p.id}')`) + - var decodedVideos = decodePostVideoUrls(p) + if query.view == "card" + video(controls="" muted="" data-dashjs-player="" preload="metadata" poster=decodedVideos[4]) + // HLS + source(src=decodedVideos[0]) + // Dash + source(src=decodedVideos[1]) + // Fallback + source(src=decodedVideos[2]) + else + video(autoplay="" muted="" data-dashjs-player="" onclick=`toggleDetails('${p.id}')` width="100px" height="100px") + // Scrubber + source(src=decodedVideos[3]) else if isPostLink(p) a(href=p.url) + if (query.view == 'card') + | #{p.domain} | ↗ - if isPostGallery(p) - details(id=`${p.id}`) - summary.expand-post expand gallery - div.gallery - each item in postGalleryItems(p) - div.gallery-item - div.gallery-item-idx - | #{`${item.idx}/${item.total}`} - a(href=`/media/${item.url}`) - img(src=item.url loading="lazy") - button(onclick=`toggleDetails('${p.id}')`) close - else if isPostImage(p) - details(id=`${p.id}`) - summary.expand-post expand image - a(href=`/media/${p.url}`) - img(src=p.url loading="lazy").post-media - button(onclick=`toggleDetails('${p.id}')`) close - else if isPostVideo(p) - details(id=`${p.id}`) - summary.expand-post expand video - - var url = p.secure_media.reddit_video.dash_url - video(src=url controls data-dashjs-player loading="lazy").post-media - button(onclick=`toggleDetails('${p.id}')`) close - else if isPostLink(p) - details(id=`${p.id}`) - summary.expand-post expand link - a(href=`${p.url}`) - | #{p.url} - br - button(onclick=`toggleDetails('${p.id}')`) close + if (isPostGallery(p) || isPostImage(p) || isPostVideo(p)) + details(id=`${p.id}`,class=`${query.view}`) + summary.expand-post expand media + div.image-viewer(class=`${query.view}`) + if isPostGallery(p) + div.gallery(class=`${query.view}`) + each item in postGalleryItems(p) + div.gallery-item(class=`${query.view}`) + div.gallery-item-idx(class=`${query.view}`) + | #{`${item.idx}/${item.total}`} + a(href=`/media/${item.url}`) + img(src=item.url loading="lazy") + else if isPostImage(p) + a(href=`/media/${p.url}`) + img(src=p.url loading="lazy").post-media + else if isPostVideo(p) + video(controls="" muted="" data-dashjs-player="" preload="metadata" playsinline="" poster=decodedVideos[4] objectfit="contain" loading="lazy").post-media + //HLS + source(src=decodedVideos[0]) + // Dash + source(src=decodedVideos[1]) + // Fallback + source(src=decodedVideos[2]) + button(onclick=`toggleDetails('${p.id}')`,class=`${query.view}`) + if (query.view == 'card') + | ╳ + else + | close diff --git a/src/mixins/postUtils.pug b/src/mixins/postUtils.pug index 816adf7..84add09 100644 --- a/src/mixins/postUtils.pug +++ b/src/mixins/postUtils.pug @@ -10,14 +10,14 @@ } - function postThumbnail(p) { - if (p.thumbnail == "image" || p.thumbnail == "") { - return p.url; - } else if (p.over_18) { - return "/nsfw.svg"; + if (p.over_18) { + return "/nsfw.svg"; } else if (p.thumbnail == "spoiler") { - return "/spoiler.svg"; + return "/spoiler.svg"; + } else if (p.thumbnail == "image" || p.thumbnail == "") { + return p.url; } else { - return p.thumbnail; + return p.thumbnail; } } - @@ -51,3 +51,33 @@ return null; } } +- + function convertInlineImageLinks(html) { + // Find all anchors that href to https://preview.redd.it + const expression = /(.*?)<\/a>/g; + const matches = html.matchAll(expression); + var result = html; + matches.forEach((match) => { + // Replace each occurrence with an actual img tag + result = result.replace(match[0], ''); + }) + + return result; + } +- + function decodePostVideoUrls(p) { + // Video URLs have querystring separators that are HTML-encoded, so replace them. + const expression = /&/g; + + var hls_url = p.secure_media && p.secure_media.reddit_video && p.secure_media.reddit_video.hls_url ? p.secure_media.reddit_video.hls_url.replace(expression, '&') : ''; + + var dash_url = p.secure_media && p.secure_media.reddit_video && p.secure_media.reddit_video.dash_url ? p.secure_media.reddit_video.dash_url.replace(expression, '&') : ''; + + var fallback_url = p.secure_media && p.secure_media.reddit_video && p.secure_media.reddit_video.fallback_url ? p.secure_media.reddit_video.fallback_url.replace(expression, '&') : ''; + + var scrubber_url = p.secure_media && p.secure_media.reddit_video && p.secure_media.reddit_video.scrubber_media_url ? p.secure_media.reddit_video.scrubber_media_url.replace(expression, '&') : ''; + + var poster_url = p.preview && p.preview.images ? p.preview.images[0].source.url.replace(expression, '&') : ''; + + return [hls_url, dash_url, fallback_url, scrubber_url, poster_url]; + } \ No newline at end of file diff --git a/src/public/styles.css b/src/public/styles.css index 3db6790..edf0042 100644 --- a/src/public/styles.css +++ b/src/public/styles.css @@ -43,6 +43,10 @@ body { color: var(--text-color); } +body:has(details.card[open]) { + overflow: hidden; +} + main { display: flex; flex-direction: column; @@ -127,6 +131,120 @@ nav { font-size: 0.9rem; } +.post-container.card { + border: 1px solid var(--bg-color-muted); + border-radius: 16px; + display: block; +} + +.post-text.card { + padding: 0.9rem; + padding-top: 0.3rem; +} + +.self-text-overflow.card { + /* For spoiler positioning */ + position: relative; + padding-top: 0.3rem; + max-height: 10vh; + overflow: hidden; + overflow-wrap: break-word; + display: block; +} + +.self-text.card { + overflow: hidden; + display: -webkit-box; + /* Safari on iOS <= 17 */ + -webkit-box-orient: vertical; + -webkit-line-clamp: 3; + line-clamp: 3; + text-overflow: ellipsis; +} + +.media-preview.card { + position: relative; + padding: 0.3rem; + padding-bottom: 0.3rem; +} + +.media-preview.card > img { + cursor: pointer; +} + +.image-viewer.card { + /* Safari on iOS <= 17 */ + -webkit-backdrop-filter: blur(2rem); + backdrop-filter: blur(2rem); + position: fixed; + inset: 0; + box-sizing: border-box; + display: flex; + height: 100%; + width: 100%; + justify-content: center; + align-items: center; + z-index: 100; +} + +.image-viewer.card > button { + position: absolute; + top: 0; + right: 0; + margin: 1rem; + padding: initial; + height: 3rem; + width: 3rem; + font-size: 2rem; + border-radius: 100%; + cursor: pointer; +} + +.image-viewer.card > a > img { + max-width: 100vw; + max-height: 100vh; + width: auto; + height: auto; +} + +.gallery.card { + align-items: center; +} + +.gallery-item.card > a > img { + max-width: 95vw; + max-height: 95vh; + width: auto; + height: auto; +} + +.spoiler { + background-color: rbga(var(--bg-color-muted), 0.2); + /* Safari on iOS <= 17 */ + -webkit-backdrop-filter: blur(3rem); + backdrop-filter: blur(3rem); + border-radius: 4px; + + position: absolute; + top: 0; + left: 0; + + box-sizing: border-box; + display: flex; + height: 100%; + width: 100%; + + justify-content: center; + align-items: center; + + cursor: pointer; +} + +.gallery-item-idx.card, +.spoiler > h2 { + text-shadow: 0.1rem 0.1rem 1rem var(--bg-color-muted); +} + .comments-container { font-size: 0.9rem; } @@ -171,6 +289,29 @@ summary::before { height: 4rem; } +.media-preview.card img, +.media-preview.card video { + border-radius: 16px; + + max-height: 40vh; + max-width: 100%; + + display: block; + width: initial; + height: initial; + margin-left: auto; + margin-right: auto; + margin-bottom: 1rem; + + object-fit: fill; +} + +.media-preview.card a { + font-size: 1.5rem; + margin: 1rem; + padding: initial; +} + .media-preview a { font-size: 2rem; text-decoration: none; @@ -225,6 +366,20 @@ form { width: 5rem; height: 5rem; } + .media-preview.card img, + .media-preview.card video + { + max-height: 50vh; + } + .media-preview.card a { + font-size: 1rem; + margin: 0.7rem; + padding: initial; + } + .self-text.card { + -webkit-line-clamp: 4; + line-clamp: 4; + } .post-author { display: inline } @@ -252,10 +407,24 @@ form { width: 5rem; height: 5rem; } + .media-preview.card img, + .media-preview.card video + { + max-height: 30vh; + } .media-preview a { font-size: 2rem; padding: 2rem; } + .media-preview.card a { + font-size: 1rem; + margin: 0.5rem; + padding: initial; + } + .self-text.card { + -webkit-line-clamp: 6; + line-clamp: 6; + } .post-author { display: inline } @@ -277,6 +446,11 @@ form { flex: 1 1 40%; width: 40%; } + .media-preview.card img, + .media-preview.card video + { + max-height: 20vh; + } .sort-opts { grid-template-columns: repeat(9, 1fr); grid-template-rows: repeat(1, 1fr); @@ -345,6 +519,11 @@ form { text-decoration: none; } +.title-container.card > a { + font-size: 1.125rem; + font-weight: bold; +} + .title-container > a:hover { text-decoration: underline; } diff --git a/src/routes/index.js b/src/routes/index.js index 117b728..9415607 100644 --- a/src/routes/index.js +++ b/src/routes/index.js @@ -16,11 +16,14 @@ router.get("/", authenticateToken, async (req, res) => { const subs = db .query("SELECT * FROM subscriptions WHERE user_id = $id") .all({ id: req.user.id }); + + const qs = req.query ? ('?' + new URLSearchParams(req.query).toString()) : ''; + if (subs.length === 0) { - res.redirect("/r/all"); + res.redirect(`/r/all${qs}`); } else { const p = subs.map((s) => s.subreddit).join("+"); - res.redirect(`/r/${p}`); + res.redirect(`/r/${p}${qs}`); } }); @@ -32,6 +35,9 @@ router.get("/r/:subreddit", authenticateToken, async (req, res) => { if (!query.sort) { query.sort = "hot"; } + if (!query.view) { + query.view = "compact"; + } let isSubbed = false; if (!isMulti) { @@ -47,6 +53,10 @@ router.get("/r/:subreddit", authenticateToken, async (req, res) => { const [posts, about] = await Promise.all([postsReq, aboutReq]); + if (query.view == 'card' && posts && posts.posts) { + posts.posts.forEach(unescape_selftext); + } + res.render("index", { subreddit, posts, @@ -71,6 +81,7 @@ router.get("/comments/:id", authenticateToken, async (req, res) => { data: unescape_submission(response), user: req.user, from: req.query.from, + query: req.query, }); }); @@ -104,12 +115,12 @@ router.get("/subs", authenticateToken, async (req, res) => { ) .all({ id: req.user.id }); - res.render("subs", { subs, user: req.user }); + res.render("subs", { subs, user: req.user, query: req.query }); }); // GET /search router.get("/search", authenticateToken, async (req, res) => { - res.render("search", { user: req.user }); + res.render("search", { user: req.user, query: req.query }); }); // GET /sub-search @@ -133,6 +144,7 @@ router.get("/sub-search", authenticateToken, async (req, res) => { message, user: req.user, original_query: req.query.q, + query: req.query, }); } }); @@ -147,6 +159,11 @@ router.get("/post-search", authenticateToken, async (req, res) => { items.length === 0 ? "no results found" : `showing ${items.length} results`; + + if (req.query.view == 'card' && items) { + items.forEach(unescape_selftext); + } + res.render("post-search", { items, after, @@ -154,6 +171,7 @@ router.get("/post-search", authenticateToken, async (req, res) => { user: req.user, original_query: req.query.q, currentUrl: req.url, + query: req.query, }); } }); @@ -176,7 +194,7 @@ router.get("/dashboard", authenticateToken, async (req, res) => { usedAt: Date.parse(inv.usedAt), })); } - res.render("dashboard", { invites, isAdmin, user: req.user }); + res.render("dashboard", { invites, isAdmin, user: req.user, query: req.query }); }); router.get("/create-invite", authenticateAdmin, async (req, res) => { @@ -359,14 +377,23 @@ function unescape_submission(response) { const post = response.submission.data; const comments = response.comments; - if (post.selftext_html) { - post.selftext_html = he.decode(post.selftext_html); - } + unescape_selftext(post); comments.forEach(unescape_comment); return { post, comments }; } +function unescape_selftext(post) { + // If called after getSubmissions + if (post.data && post.data.selftext_html) { + post.data.selftext_html = he.decode(post.data.selftext_html); + } + // If called after getSubmissionComments + if (post.selftext_html) { + post.selftext_html = he.decode(post.selftext_html); + } +} + function unescape_comment(comment) { if (comment.data.body_html) { comment.data.body_html = he.decode(comment.data.body_html); diff --git a/src/views/comments.pug b/src/views/comments.pug index 17af45a..1caf65a 100644 --- a/src/views/comments.pug +++ b/src/views/comments.pug @@ -6,6 +6,8 @@ include ../utils - var post = data.post - var comments = data.comments +- var viewQuery = 'view=' + (query && query.view ? query.view : 'compact') +- var sortQuery = 'sort=' + (query && query.sort ? query.sort + (query.t ? '&t=' + query.t : '') : 'hot') doctype html html +head(post.title) @@ -27,7 +29,7 @@ html |    | · |    - a(href=`/r/${post.subreddit}`) r/#{post.subreddit} + a(href=`/r/${post.subreddit}?${sortQuery}&${viewQuery}`) r/#{post.subreddit} div.info-container - var domain = (new URL(post.url)).hostname @@ -65,7 +67,7 @@ html if post.selftext_html div.self-text - != post.selftext_html + != convertInlineImageLinks(post.selftext_html) hr diff --git a/src/views/index.pug b/src/views/index.pug index 0f00efe..5c7d550 100644 --- a/src/views/index.pug +++ b/src/views/index.pug @@ -2,6 +2,8 @@ include ../mixins/post include ../mixins/header include ../mixins/head include ../utils + - var viewQuery = query && query.view ? query.view : 'compact' + - var sortQuery = query && query.sort ? query.sort + (query.t ? '&t=' + query.t : '') : 'hot' doctype html html +head("home") @@ -14,9 +16,9 @@ html div.sub-title h1 if isMulti - a(href=`/`) lurker + a(href=`/?${sortQuery}&${viewQuery}`) lurker else - a(href=`/r/${subreddit}`) + a(href=`/r/${subreddit}?${sortQuery}&${viewQuery}`) | r/#{subreddit} if !isMulti div#button-container @@ -32,27 +34,32 @@ html a(href="https://donate.stripe.com/dR62bTaZH1295Da4gg") oppiliappan |, author of lurker hr - details - summary.sorting sorting by #{query.sort + (query.t?' '+query.t:'')} + details.sort-details + summary.sorting sorting by #{query.sort + (query.t?' '+query.t:'')}, #{viewQuery} view div.sort-opts div - a(href=`/r/${subreddit}?sort=hot`) hot + a(href=`/r/${subreddit}?sort=hot&view=${viewQuery}`) hot div - a(href=`/r/${subreddit}?sort=new`) new + a(href=`/r/${subreddit}?sort=new&view=${viewQuery}`) new div - a(href=`/r/${subreddit}?sort=rising`) rising + a(href=`/r/${subreddit}?sort=rising&view=${viewQuery}`) rising div - a(href=`/r/${subreddit}?sort=top`) top + a(href=`/r/${subreddit}?sort=top&view=${viewQuery}`) top div - a(href=`/r/${subreddit}?sort=top&t=day`) top day + a(href=`/r/${subreddit}?sort=top&t=day&view=${viewQuery}`) top day div - a(href=`/r/${subreddit}?sort=top&t=week`) top week + a(href=`/r/${subreddit}?sort=top&t=week&view=${viewQuery}`) top week div - a(href=`/r/${subreddit}?sort=top&t=month`) top month + a(href=`/r/${subreddit}?sort=top&t=month&view=${viewQuery}`) top month div - a(href=`/r/${subreddit}?sort=top&t=year`) top year + a(href=`/r/${subreddit}?sort=top&t=year&view=${viewQuery}`) top year div - a(href=`/r/${subreddit}?sort=top&t=all`) top all + a(href=`/r/${subreddit}?sort=top&t=all&view=${viewQuery}`) top all + div.sort-opts + div + a(href=`/r/${subreddit}?sort=${sortQuery}&view=compact`) compact + div + a(href=`/r/${subreddit}?sort=${sortQuery}&view=card`) card if posts each child in posts.posts diff --git a/src/views/post-search.pug b/src/views/post-search.pug index b80f9f6..8f93798 100644 --- a/src/views/post-search.pug +++ b/src/views/post-search.pug @@ -2,6 +2,8 @@ include ../mixins/post include ../mixins/header include ../mixins/head +- var viewQuery = query && query.view ? query.view : 'compact' +- var sortQuery = query && query.sort ? query.sort + (query.t ? '&t=' + query.t : '') : 'hot' doctype html html +head("search posts") @@ -14,6 +16,8 @@ html form(action="/post-search" method="get").search-bar - var prefill = original_query ?? ""; input(type="text" name="q" placeholder="type in a search term..." value=prefill required).search-input + input(type="hidden" name="sort" value=sortQuery) + input(type="hidden" name="view" value=viewQuery) button(type="submit").search-button go if message div.search-message diff --git a/src/views/search.pug b/src/views/search.pug index ef9b53e..4dc5c0c 100644 --- a/src/views/search.pug +++ b/src/views/search.pug @@ -1,6 +1,8 @@ include ../mixins/header include ../mixins/head +- var viewQuery = query && query.view ? query.view : 'compact' +- var sortQuery = query && query.sort ? query.sort + (query.t ? '&t=' + query.t : '') : 'hot' doctype html html +head("search subreddits") @@ -14,6 +16,8 @@ html form(action="/sub-search" method="get").search-bar - var prefill = original_query ?? ""; input(type="text" name="q" placeholder="type in a search term..." value=prefill required).search-input + input(type="hidden" name="sort" value=sortQuery) + input(type="hidden" name="view" value=viewQuery) button(type="submit").search-button go hr @@ -23,6 +27,8 @@ html form(action="/post-search" method="get").search-bar - var prefill = original_query ?? ""; input(type="text" name="q" placeholder="type in a search term..." value=prefill required).search-input + input(type="hidden" name="sort" value=sortQuery) + input(type="hidden" name="view" value=viewQuery) button(type="submit").search-button go p | you can narrow search results using filters: diff --git a/src/views/sub-search.pug b/src/views/sub-search.pug index f2402f7..cb8eeef 100644 --- a/src/views/sub-search.pug +++ b/src/views/sub-search.pug @@ -1,6 +1,8 @@ include ../mixins/header include ../mixins/head +- var viewQuery = (query && query.view) ? query.view : 'compact' +- var sortQuery = (query && query.sort) ? query.sort + (query.t ? '&t=' + query.t : '') : 'hot' doctype html html +head("search subreddits") @@ -13,6 +15,8 @@ html form(action="/sub-search" method="get").search-bar - var prefill = original_query ?? ""; input(type="text" name="q" placeholder="type in a search term..." value=prefill required).search-input + input(type="hidden" name="sort" value=sortQuery) + input(type="hidden" name="view" value=viewQuery) button(type="submit").search-button go if message div.search-message @@ -25,7 +29,7 @@ html - var isSubbed = subs.includes(subreddit) div.sub-title h3 - a(href=`/r/${subreddit}`) + a(href=`/r/${subreddit}?sort=${sortQuery}&view=${viewQuery}`) | r/#{subreddit} div#button-container if isSubbed diff --git a/src/views/subs.pug b/src/views/subs.pug index 8fca12d..aff8258 100644 --- a/src/views/subs.pug +++ b/src/views/subs.pug @@ -1,6 +1,8 @@ include ../mixins/header include ../mixins/head +- var viewQuery = query && query.view ? query.view : 'compact' +- var sortQuery = query && query.sort ? query.sort + (query.t ? '&t=' + query.t : '') : 'hot' doctype html html +head("subscriptions") @@ -16,7 +18,7 @@ html - var isSubbed = true div.sub-title h4 - a(href=`/r/${subreddit}`) + a(href=`/r/${subreddit}?sort=${sortQuery}&view=${viewQuery}`) | r/#{subreddit} div#button-container if isSubbed -- cgit v1.2.3 From 12fba690f13ad288dfd86070e31b97f7e69a2070 Mon Sep 17 00:00:00 2001 From: Akshay Date: Sun, 29 Dec 2024 10:49:18 +0000 Subject: highlight sticky comments --- src/mixins/comment.pug | 8 ++++++-- src/mixins/post.pug | 2 +- src/public/styles.css | 13 +++++++++++++ 3 files changed, 20 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/mixins/comment.pug b/src/mixins/comment.pug index 3eca723..ffd4b5a 100644 --- a/src/mixins/comment.pug +++ b/src/mixins/comment.pug @@ -1,6 +1,7 @@ include ../utils mixin infoContainer(data, next_id, prev_id) + - var hats = (data.is_submitter?['op']:[]).concat(data.distinguished=="moderator"?['mod']:[]) div.comment-info-container p | #{fmtnum(data.ups)} ↑ @@ -12,7 +13,7 @@ mixin infoContainer(data, next_id, prev_id) a(href=`#${prev_id}` title="scroll to previous comment").nav-link prev |  ·  span(class=`${data.is_submitter ? 'op' : ''}`) - | u/#{data.author} #{data.is_submitter ? '(op)' : ''} + | u/#{data.author} #{hats.length==0?'':`(${hats.join('|')})`} |  ·  if data.collapsed_reason_code == "DELETED" || data.author == "[deleted]" a(href=`https://undelete.pullpush.io${data.permalink}`) search on undelete @@ -22,6 +23,9 @@ mixin infoContainer(data, next_id, prev_id) if data.edited !== false | edited #{timeDifference(Date.now(), data.edited * 1000)} ago |  ·  + if data.stickied + | stickied + |  ·  a(href=`https://reddit.com${data.permalink}` title="view on reddit").nav-link open ↗ - @@ -38,7 +42,7 @@ mixin comment(com, isfirst, parent_id, next_id, prev_id) a(href=`/comments/${parent_id}/comment/${data.id}`) | #{data.count} more #{fmttxt(data.count, 'comment')} else - div(class=`comment ${isfirst ? 'first' : ''}`) + div(class=`comment ${isfirst ? 'first' : ''} ${data.stickied ? 'sticky' : ''}`) details(id=`${data.id}` open="") summary.expand-comments +infoContainer(data, next_id, prev_id) diff --git a/src/mixins/post.pug b/src/mixins/post.pug index 4022424..26dc976 100644 --- a/src/mixins/post.pug +++ b/src/mixins/post.pug @@ -4,7 +4,7 @@ mixin post(p, currentUrl) - var from = encodeURIComponent(currentUrl) - var viewQuery = query && query.view ? query.view : 'compact' - var sortQuery = query && query.sort ? query.sort + (query.t ? '&t=' + query.t : '') : 'hot' - article.post + article(class=`post ${p.stickied?"sticky":""}`) div.post-container(class=`${query.view}`) div.post-text(class=`${query.view}`) div.title-container(class=`${query.view}`) diff --git a/src/public/styles.css b/src/public/styles.css index edf0042..1cd5245 100644 --- a/src/public/styles.css +++ b/src/public/styles.css @@ -5,6 +5,7 @@ --text-color: black; --text-color-muted: #999; --blockquote-color: green; + --sticky-color: lightgreen; --link-color: #29BC9B; --link-visited-color: #999; --accent: var(--link-color); @@ -22,6 +23,7 @@ --text-color: white; --text-color-muted: #999; --blockquote-color: lightgreen; + --sticky-color: #034611; --link-color: #79ffe1; --link-visited-color: #999; --accent: var(--link-color); @@ -121,6 +123,10 @@ nav { align-items: stretch; } +.post { + margin-bottom: 5px; +} + .post, .comments-container, .hero, .header, .footer { padding: 0.3rem; flex: 1 1 95%; @@ -791,3 +797,10 @@ select { text-indent: 1px; text-overflow: ''; } + +.sticky { + background-color: var(--sticky-color); + border-radius: 2px; + border: 4px solid var(--sticky-color); +} + -- cgit v1.2.3 From 335446560f3e4765e3d8d9979c2aa52110499786 Mon Sep 17 00:00:00 2001 From: Akshay Date: Mon, 30 Dec 2024 10:24:08 +0000 Subject: fix colors, show gildings --- src/mixins/comment.pug | 4 ++++ src/mixins/post.pug | 4 ++++ src/public/styles.css | 11 ++++++++--- 3 files changed, 16 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/mixins/comment.pug b/src/mixins/comment.pug index ffd4b5a..5b6f097 100644 --- a/src/mixins/comment.pug +++ b/src/mixins/comment.pug @@ -12,6 +12,10 @@ mixin infoContainer(data, next_id, prev_id) if prev_id a(href=`#${prev_id}` title="scroll to previous comment").nav-link prev |  ·  + if data.gilded > 0 + span.gilded + | #{data.gilded} ☆ + |  ·  span(class=`${data.is_submitter ? 'op' : ''}`) | u/#{data.author} #{hats.length==0?'':`(${hats.join('|')})`} |  ·  diff --git a/src/mixins/post.pug b/src/mixins/post.pug index 26dc976..a9fd7c4 100644 --- a/src/mixins/post.pug +++ b/src/mixins/post.pug @@ -14,6 +14,10 @@ mixin post(p, currentUrl) div.info-container p | #{fmtnum(p.ups)} ↑ + if p.gilded > 0 + |  ·  + span.gilded + | #{p.gilded} ☆ span.post-author |  ·  | u/#{p.author} diff --git a/src/public/styles.css b/src/public/styles.css index 1cd5245..5996c75 100644 --- a/src/public/styles.css +++ b/src/public/styles.css @@ -5,7 +5,8 @@ --text-color: black; --text-color-muted: #999; --blockquote-color: green; - --sticky-color: lightgreen; + --sticky-color: #dcfeda; + --gilded: darkorange; --link-color: #29BC9B; --link-visited-color: #999; --accent: var(--link-color); @@ -23,7 +24,8 @@ --text-color: white; --text-color-muted: #999; --blockquote-color: lightgreen; - --sticky-color: #034611; + --sticky-color: #014413; + --gilded: gold; --link-color: #79ffe1; --link-visited-color: #999; --accent: var(--link-color); @@ -654,6 +656,10 @@ a { color: var(--accent); } +.gilded { + color: var(--gilded); +} + button { border: 0px solid; border-radius: 2px; @@ -803,4 +809,3 @@ select { border-radius: 2px; border: 4px solid var(--sticky-color); } - -- cgit v1.2.3 From fc5a28a9c3ea695b5b0f5c65e0c8a5ad5c83dec1 Mon Sep 17 00:00:00 2001 From: Nick Warner <60248569+PortableProgrammer@users.noreply.github.com> Date: Thu, 2 Jan 2025 08:51:23 -0700 Subject: Fix subtitle subreddit link sort/view querystrings --- src/views/index.pug | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/views/index.pug b/src/views/index.pug index 5c7d550..847adbb 100644 --- a/src/views/index.pug +++ b/src/views/index.pug @@ -16,9 +16,9 @@ html div.sub-title h1 if isMulti - a(href=`/?${sortQuery}&${viewQuery}`) lurker + a(href=`/?sort=${sortQuery}&view=${viewQuery}`) lurker else - a(href=`/r/${subreddit}?${sortQuery}&${viewQuery}`) + a(href=`/r/${subreddit}?sort=${sortQuery}&view=${viewQuery}`) | r/#{subreddit} if !isMulti div#button-container -- cgit v1.2.3 From 0cfd4af340ee14fa92d676b54b25ee66c4d4824c Mon Sep 17 00:00:00 2001 From: PortableProgrammer Date: Sat, 4 Jan 2025 17:37:47 +0000 Subject: Tweak sticky background in card view --- src/mixins/post.pug | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/mixins/post.pug b/src/mixins/post.pug index a9fd7c4..2e77402 100644 --- a/src/mixins/post.pug +++ b/src/mixins/post.pug @@ -4,8 +4,8 @@ mixin post(p, currentUrl) - var from = encodeURIComponent(currentUrl) - var viewQuery = query && query.view ? query.view : 'compact' - var sortQuery = query && query.sort ? query.sort + (query.t ? '&t=' + query.t : '') : 'hot' - article(class=`post ${p.stickied?"sticky":""}`) - div.post-container(class=`${query.view}`) + article(class=`post`) + div.post-container(class=`${query.view} ${p.stickied?"sticky":""}`) div.post-text(class=`${query.view}`) div.title-container(class=`${query.view}`) a(class=`${query.view}`, href=`/comments/${p.id}?from=${from}&sort=${sortQuery}&view=${viewQuery}`) -- cgit v1.2.3 From 9793c5e0ec707b967f770242b22950e1741341a6 Mon Sep 17 00:00:00 2001 From: PortableProgrammer Date: Sat, 4 Jan 2025 18:16:31 +0000 Subject: Detect `preview.redd.it`, `i.redd.it`, and `i.imgur.com` inline links and expand them to image tags in card view and comments. --- src/mixins/comment.pug | 3 ++- src/mixins/postUtils.pug | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/mixins/comment.pug b/src/mixins/comment.pug index 5b6f097..0609587 100644 --- a/src/mixins/comment.pug +++ b/src/mixins/comment.pug @@ -1,4 +1,5 @@ include ../utils +include postUtils mixin infoContainer(data, next_id, prev_id) - var hats = (data.is_submitter?['op']:[]).concat(data.distinguished=="moderator"?['mod']:[]) @@ -51,7 +52,7 @@ mixin comment(com, isfirst, parent_id, next_id, prev_id) summary.expand-comments +infoContainer(data, next_id, prev_id) div.comment-body - != data.body_html + != convertInlineImageLinks(data.body_html) if hasReplyData div.replies - var total = data.replies.data.children.length diff --git a/src/mixins/postUtils.pug b/src/mixins/postUtils.pug index 84add09..b778cbd 100644 --- a/src/mixins/postUtils.pug +++ b/src/mixins/postUtils.pug @@ -53,8 +53,9 @@ } - function convertInlineImageLinks(html) { - // Find all anchors that href to https://preview.redd.it - const expression = /(.*?)<\/a>/g; + // Find all anchors that href to preview.redd.it, i.redd.it, i.imgur.com + // and contain just a link to the same href + const expression = /\1?<\/a>/g; const matches = html.matchAll(expression); var result = html; matches.forEach((match) => { -- cgit v1.2.3 From 07702b73c4d4dfeacdb19cd7928e401712ada8a8 Mon Sep 17 00:00:00 2001 From: PortableProgrammer Date: Tue, 7 Jan 2025 16:17:58 +0000 Subject: Feat: Card View Restrict inline image links width to a reasonable size --- src/mixins/postUtils.pug | 2 +- src/public/styles.css | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/mixins/postUtils.pug b/src/mixins/postUtils.pug index b778cbd..b96ff1e 100644 --- a/src/mixins/postUtils.pug +++ b/src/mixins/postUtils.pug @@ -60,7 +60,7 @@ var result = html; matches.forEach((match) => { // Replace each occurrence with an actual img tag - result = result.replace(match[0], ''); + result = result.replace(match[0], ''); }) return result; diff --git a/src/public/styles.css b/src/public/styles.css index 5996c75..bba485e 100644 --- a/src/public/styles.css +++ b/src/public/styles.css @@ -809,3 +809,7 @@ select { border-radius: 2px; border: 4px solid var(--sticky-color); } + +.inline { + max-width: 100%; +} -- cgit v1.2.3 From 7db14056d32575cf3cb7bed927ea0d9189efeebc Mon Sep 17 00:00:00 2001 From: PortableProgrammer Date: Wed, 8 Jan 2025 15:34:20 +0000 Subject: Feat: Card View - reduce `border-radius` intensity --- src/public/styles.css | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/public/styles.css b/src/public/styles.css index bba485e..7a6345a 100644 --- a/src/public/styles.css +++ b/src/public/styles.css @@ -141,7 +141,7 @@ nav { .post-container.card { border: 1px solid var(--bg-color-muted); - border-radius: 16px; + border-radius: 8px; display: block; } @@ -299,7 +299,7 @@ summary::before { .media-preview.card img, .media-preview.card video { - border-radius: 16px; + border-radius: 6px; max-height: 40vh; max-width: 100%; -- cgit v1.2.3 From dcd33d89e28c97cc620397d912316a116ac091ba Mon Sep 17 00:00:00 2001 From: PortableProgrammer Date: Wed, 8 Jan 2025 16:06:14 +0000 Subject: Feat: Card View - Separate sort and view detail options --- src/views/index.pug | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/views/index.pug b/src/views/index.pug index 847adbb..9f5142b 100644 --- a/src/views/index.pug +++ b/src/views/index.pug @@ -35,7 +35,7 @@ html |, author of lurker hr details.sort-details - summary.sorting sorting by #{query.sort + (query.t?' '+query.t:'')}, #{viewQuery} view + summary.sorting sorting by #{query.sort + (query.t?' '+query.t:'')} div.sort-opts div a(href=`/r/${subreddit}?sort=hot&view=${viewQuery}`) hot @@ -55,6 +55,8 @@ html a(href=`/r/${subreddit}?sort=top&t=year&view=${viewQuery}`) top year div a(href=`/r/${subreddit}?sort=top&t=all&view=${viewQuery}`) top all + details.sort-details + summary.sorting viewing as #{viewQuery} div.sort-opts div a(href=`/r/${subreddit}?sort=${sortQuery}&view=compact`) compact -- cgit v1.2.3 From e351d76a0e3dfc99a2ea3747ecb3aa06c7c6a613 Mon Sep 17 00:00:00 2001 From: PortableProgrammer Date: Wed, 8 Jan 2025 17:44:39 +0000 Subject: Feat: Card View - Update `media` page, allow zooming --- src/public/styles.css | 33 ++++++++++++++++++++++++--------- src/views/media.pug | 11 ++++++++--- 2 files changed, 32 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/public/styles.css b/src/public/styles.css index 7a6345a..abc2f13 100644 --- a/src/public/styles.css +++ b/src/public/styles.css @@ -51,6 +51,21 @@ body:has(details.card[open]) { overflow: hidden; } +body.media-maximized { + /* Fix for Safari User Agent stylesheet */ + margin: 0; +} + +body.media-maximized.zoom, +div.media-maximized.container.zoom { + overflow: auto; +} + +img.media-maximized.zoom { + max-width: unset; + max-height: unset; +} + main { display: flex; flex-direction: column; @@ -326,15 +341,6 @@ summary::before { padding: 1rem; } -.media-maximized-container { - display: flex; - justify-content: center; - align-items: center; - width: 100vw; - height: 100vh; - overflow: hidden; -} - .media-maximized { max-width: 100vw; max-height: 100vh; @@ -345,6 +351,15 @@ summary::before { object-fit: contain; } +.media-maximized.container { + display: flex; + justify-content: center; + align-items: center; + width: 100vw; + height: 100vh; + overflow: hidden; +} + .post-author { display: none } diff --git a/src/views/media.pug b/src/views/media.pug index 4476dbb..e945704 100644 --- a/src/views/media.pug +++ b/src/views/media.pug @@ -2,9 +2,14 @@ include ../mixins/head doctype html html +head("home") - body - div.media-maximized-container + script(type='text/javascript'). + function toggleZoom() { + Array.from(document.getElementsByClassName('media-maximized')).forEach(element => element.classList.toggle('zoom')); + } + + body.media-maximized + div.media-maximized.container if kind == 'img' - img(src=url).media-maximized + img(src=url onclick=`toggleZoom()`).media-maximized else video(src=url controls).media-maximized -- cgit v1.2.3 From 3cd139f528f6c8d8186843e800672d16fd1c5558 Mon Sep 17 00:00:00 2001 From: PortableProgrammer Date: Wed, 8 Jan 2025 17:45:37 +0000 Subject: Feat: Card View - Use `media` view instead of preview div --- src/mixins/post.pug | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/mixins/post.pug b/src/mixins/post.pug index 2e77402..36ea1b8 100644 --- a/src/mixins/post.pug +++ b/src/mixins/post.pug @@ -36,16 +36,27 @@ mixin post(p, currentUrl) div.self-text(class='card') != convertInlineImageLinks(p.selftext_html) div.media-preview(class=`${query.view}`) + - var onclick = query.view != "card" ? `toggleDetails('${p.id}')` : `` if query.view == "card" && (p.spoiler || p.over_18) && (isPostGallery(p) || isPostImage(p) || isPostVideo(p)) div.spoiler(id=`spoiler_${p.id}`, onclick=`javascript:document.getElementById('spoiler_${p.id}').style.display = 'none';`) h2 != p.over_18 ? 'nsfw' : 'spoiler' if isPostGallery(p) - var item = postGalleryItems(p)[0] - img(src=item.url onclick=`toggleDetails('${p.id}')`) + if query.view == "card" + div.gallery(class=`${query.view}`) + each item in postGalleryItems(p) + div.gallery-item(class=`${query.view}`) + div.gallery-item-idx(class=`${query.view}`) + | #{`${item.idx}/${item.total}`} + a(href=`/media/${item.url}`) + img(src=item.url loading="lazy") + else + img(src=item.url onclick=onclick) else if isPostImage(p) - var url = query.view == "card" ? p.url : postThumbnail(p) - img(src=url onclick=`toggleDetails('${p.id}')`) + #{query.view == "card" ? "a href=/media/" + url : span} + img(src=url onclick=onclick) else if isPostVideo(p) - var decodedVideos = decodePostVideoUrls(p) if query.view == "card" -- cgit v1.2.3 From 2c4522bef5c2f7b223b69d910a428c9c0eabb3d5 Mon Sep 17 00:00:00 2001 From: PortableProgrammer Date: Wed, 8 Jan 2025 18:00:18 +0000 Subject: Remove `card`-specific `post` elements --- src/mixins/post.pug | 53 ++++++++++++++++++++++++--------------------------- src/public/styles.css | 40 +++++--------------------------------- 2 files changed, 30 insertions(+), 63 deletions(-) (limited to 'src') diff --git a/src/mixins/post.pug b/src/mixins/post.pug index 36ea1b8..df499e2 100644 --- a/src/mixins/post.pug +++ b/src/mixins/post.pug @@ -77,31 +77,28 @@ mixin post(p, currentUrl) | #{p.domain} | ↗ - if (isPostGallery(p) || isPostImage(p) || isPostVideo(p)) - details(id=`${p.id}`,class=`${query.view}`) - summary.expand-post expand media - div.image-viewer(class=`${query.view}`) - if isPostGallery(p) - div.gallery(class=`${query.view}`) - each item in postGalleryItems(p) - div.gallery-item(class=`${query.view}`) - div.gallery-item-idx(class=`${query.view}`) - | #{`${item.idx}/${item.total}`} - a(href=`/media/${item.url}`) - img(src=item.url loading="lazy") - else if isPostImage(p) - a(href=`/media/${p.url}`) - img(src=p.url loading="lazy").post-media - else if isPostVideo(p) - video(controls="" muted="" data-dashjs-player="" preload="metadata" playsinline="" poster=decodedVideos[4] objectfit="contain" loading="lazy").post-media - //HLS - source(src=decodedVideos[0]) - // Dash - source(src=decodedVideos[1]) - // Fallback - source(src=decodedVideos[2]) - button(onclick=`toggleDetails('${p.id}')`,class=`${query.view}`) - if (query.view == 'card') - | ╳ - else - | close + if query.view == "compact" && (isPostGallery(p) || isPostImage(p) || isPostVideo(p)) + details(id=`${p.id}`) + summary.expand-post expand media + div.image-viewer + if isPostGallery(p) + div.gallery + each item in postGalleryItems(p) + div.gallery-item + div.gallery-item-idx + | #{`${item.idx}/${item.total}`} + a(href=`/media/${item.url}`) + img(src=item.url loading="lazy") + else if isPostImage(p) + a(href=`/media/${p.url}`) + img(src=p.url loading="lazy").post-media + else if isPostVideo(p) + video(controls="" muted="" data-dashjs-player="" preload="metadata" playsinline="" poster=decodedVideos[4] objectfit="contain" loading="lazy").post-media + //HLS + source(src=decodedVideos[0]) + // Dash + source(src=decodedVideos[1]) + // Fallback + source(src=decodedVideos[2]) + button(onclick=`toggleDetails('${p.id}')`) + | close diff --git a/src/public/styles.css b/src/public/styles.css index abc2f13..b1d1318 100644 --- a/src/public/styles.css +++ b/src/public/styles.css @@ -61,9 +61,14 @@ div.media-maximized.container.zoom { overflow: auto; } +img.media-maximized { + cursor: zoom-in; +} + img.media-maximized.zoom { max-width: unset; max-height: unset; + cursor: zoom-out; } main { @@ -195,41 +200,6 @@ nav { cursor: pointer; } -.image-viewer.card { - /* Safari on iOS <= 17 */ - -webkit-backdrop-filter: blur(2rem); - backdrop-filter: blur(2rem); - position: fixed; - inset: 0; - box-sizing: border-box; - display: flex; - height: 100%; - width: 100%; - justify-content: center; - align-items: center; - z-index: 100; -} - -.image-viewer.card > button { - position: absolute; - top: 0; - right: 0; - margin: 1rem; - padding: initial; - height: 3rem; - width: 3rem; - font-size: 2rem; - border-radius: 100%; - cursor: pointer; -} - -.image-viewer.card > a > img { - max-width: 100vw; - max-height: 100vh; - width: auto; - height: auto; -} - .gallery.card { align-items: center; } -- cgit v1.2.3 From 73465b81a69b0fcdfd038fb21e742d827166a1b5 Mon Sep 17 00:00:00 2001 From: PortableProgrammer Date: Wed, 8 Jan 2025 19:12:49 +0000 Subject: Tweak gallery img size in `card` view. Ensure `spoiler`/`nsfw` div is above everything else --- src/public/styles.css | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/public/styles.css b/src/public/styles.css index b1d1318..170c4b7 100644 --- a/src/public/styles.css +++ b/src/public/styles.css @@ -206,7 +206,7 @@ nav { .gallery-item.card > a > img { max-width: 95vw; - max-height: 95vh; + max-height: 30vh; width: auto; height: auto; } @@ -231,6 +231,8 @@ nav { align-items: center; cursor: pointer; + + z-index: 10; } .gallery-item-idx.card, -- cgit v1.2.3 From c8c23b9980d2c60a92926bf9d09b177749f9af2b Mon Sep 17 00:00:00 2001 From: PortableProgrammer Date: Wed, 8 Jan 2025 20:32:24 +0000 Subject: Tweak gallery item width --- src/public/styles.css | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/public/styles.css b/src/public/styles.css index 170c4b7..18130ed 100644 --- a/src/public/styles.css +++ b/src/public/styles.css @@ -204,11 +204,8 @@ nav { align-items: center; } -.gallery-item.card > a > img { - max-width: 95vw; - max-height: 30vh; - width: auto; - height: auto; +.gallery-item.card { + max-width: 100%; } .spoiler { -- cgit v1.2.3 From 44d4ab8040c6d423a6761512f543b661dea30bf7 Mon Sep 17 00:00:00 2001 From: PortableProgrammer Date: Wed, 8 Jan 2025 20:58:20 +0000 Subject: Make gallery nicer in card view --- src/mixins/post.pug | 4 ++-- src/public/styles.css | 7 +++++++ 2 files changed, 9 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/mixins/post.pug b/src/mixins/post.pug index df499e2..c4f3bc5 100644 --- a/src/mixins/post.pug +++ b/src/mixins/post.pug @@ -47,10 +47,10 @@ mixin post(p, currentUrl) div.gallery(class=`${query.view}`) each item in postGalleryItems(p) div.gallery-item(class=`${query.view}`) - div.gallery-item-idx(class=`${query.view}`) - | #{`${item.idx}/${item.total}`} a(href=`/media/${item.url}`) img(src=item.url loading="lazy") + div.gallery-item-idx(class=`${query.view}`) + | #{`${item.idx}/${item.total}`} else img(src=item.url onclick=onclick) else if isPostImage(p) diff --git a/src/public/styles.css b/src/public/styles.css index 18130ed..7d70725 100644 --- a/src/public/styles.css +++ b/src/public/styles.css @@ -202,10 +202,17 @@ nav { .gallery.card { align-items: center; + scroll-snap-type: both mandatory; } .gallery-item.card { max-width: 100%; + width: 100%; + scroll-snap-align: center; +} + +.gallery-item-idx.card { + text-align: center; } .spoiler { -- cgit v1.2.3 From 7314a7a686c87b72712d928bf017ae2d173f6ff2 Mon Sep 17 00:00:00 2001 From: PortableProgrammer Date: Wed, 8 Jan 2025 22:16:34 +0000 Subject: Futher tweak card view styling for small screens, fix --- src/public/styles.css | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/public/styles.css b/src/public/styles.css index 7d70725..41c9613 100644 --- a/src/public/styles.css +++ b/src/public/styles.css @@ -288,27 +288,36 @@ summary::before { height: 4rem; } +.media-preview.card { + padding: unset; +} + .media-preview.card img, .media-preview.card video { border-radius: 6px; max-height: 40vh; - max-width: 100%; + max-width: 95%; display: block; - width: initial; - height: initial; + width: unset; + height: unset; margin-left: auto; margin-right: auto; - margin-bottom: 1rem; + margin-bottom: 0.5rem; object-fit: fill; } .media-preview.card a { font-size: 1.5rem; - margin: 1rem; - padding: initial; + padding: unset; + padding-left: 1rem; +} + +.media-preview.card a:has(img) { + font-size: 0rem; + padding: unset; } .media-preview a { -- cgit v1.2.3 From 1c5214d6c35feeb685a55ed8a27b37af62c0ad36 Mon Sep 17 00:00:00 2001 From: PortableProgrammer Date: Wed, 8 Jan 2025 22:21:06 +0000 Subject: Use separate styles for sort/vew opts to utilize appropriate `grid-template-rows` values --- src/public/styles.css | 24 ++++++++++++++++++------ src/views/index.pug | 6 +++--- 2 files changed, 21 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/public/styles.css b/src/public/styles.css index 41c9613..d9f6a40 100644 --- a/src/public/styles.css +++ b/src/public/styles.css @@ -82,6 +82,7 @@ main { .info-container a, .comment-info-container a, .sort-opts a, +.view-opts a, .more a { text-decoration: none; @@ -116,21 +117,28 @@ a:visited { align-items: center; } -.sorting { +.sorting, +.viewing { margin-top: 20px; } -.sort-opts { +.sort-opts, +.view-opts { display: grid; margin: 10px; } -.sort-opts { +.sort-opts, +.view-opts { grid-template-columns: repeat(2, 1fr); grid-template-rows: repeat(5, 1fr); grid-auto-flow: column; } +.view-opts { + grid-template-rows: repeat(2, 1fr); +} + .footer { display: flex; flex-direction: row; @@ -397,7 +405,8 @@ form { form { width: 40%; } - .sort-opts { + .sort-opts, + .view-opts { grid-template-columns: repeat(9, 1fr); grid-template-rows: repeat(1, 1fr); grid-auto-flow: row; @@ -442,7 +451,8 @@ form { form { width: 20%; } - .sort-opts { + .sort-opts, + .view-opts { grid-template-columns: repeat(9, 1fr); grid-template-rows: repeat(1, 1fr); grid-auto-flow: row; @@ -459,7 +469,8 @@ form { { max-height: 20vh; } - .sort-opts { + .sort-opts, + .view-opts { grid-template-columns: repeat(9, 1fr); grid-template-rows: repeat(1, 1fr); grid-auto-flow: row; @@ -542,6 +553,7 @@ form { .header a, .sort-opts a, +.view-opts a, .sub-title a { color: var(--text-color); } diff --git a/src/views/index.pug b/src/views/index.pug index 9f5142b..a35837b 100644 --- a/src/views/index.pug +++ b/src/views/index.pug @@ -55,9 +55,9 @@ html a(href=`/r/${subreddit}?sort=top&t=year&view=${viewQuery}`) top year div a(href=`/r/${subreddit}?sort=top&t=all&view=${viewQuery}`) top all - details.sort-details - summary.sorting viewing as #{viewQuery} - div.sort-opts + details.view-details + summary.viewing viewing as #{viewQuery} + div.view-opts div a(href=`/r/${subreddit}?sort=${sortQuery}&view=compact`) compact div -- cgit v1.2.3