diff --git a/public/s/css/f0ckm.css b/public/s/css/f0ckm.css index f428a9a..7520697 100644 --- a/public/s/css/f0ckm.css +++ b/public/s/css/f0ckm.css @@ -14410,10 +14410,10 @@ body.scroller-active #gchat-reopen-bubble { /* Filter badge style on navbar */ .filter-badge { position: absolute; - bottom: -13px; - font-size: 8px; + bottom: -14px; + font-size: 9px; font-weight: 800; - padding: 1px 4px; + padding: 2px 4px; line-height: 1; text-transform: uppercase; color: #fff !important; @@ -14705,4 +14705,10 @@ body.scroller-active #gchat-reopen-bubble { padding: 0 !important; font-size: 11px !important; line-height: 1 !important; +} + +/* Sidebar activity thumbnails blur support (SFW/Untagged only; NSFW/NSFL use pre-blurred static images directly) */ +.blur-sfw-active .sidebar-thumb-link[data-mode="sfw"] img, +.blur-untagged-active .sidebar-thumb-link[data-mode="untagged"] img { + filter: blur(8px) contrast(0.85) brightness(0.85); } \ No newline at end of file diff --git a/public/s/js/sidebar-activity.js b/public/s/js/sidebar-activity.js index f775d7b..cdee132 100644 --- a/public/s/js/sidebar-activity.js +++ b/public/s/js/sidebar-activity.js @@ -397,13 +397,30 @@ let itemPreview = ''; if (c.item_id) { let mediaHtml = ''; + const rClass = c.item_rating_class || 'untagged'; + const blurNsfw = localStorage.getItem('blurNsfw') === 'true'; + const blurNsfl = localStorage.getItem('blurNsfl') === 'true'; + const blurSfw = localStorage.getItem('blurSfw') === 'true'; + const blurUntagged = localStorage.getItem('blurUntagged') === 'true'; + + let isBlurred = false; + if (rClass === 'nsfw' && blurNsfw) isBlurred = true; + else if (rClass === 'nsfl' && blurNsfl) isBlurred = true; + else if (rClass === 'sfw' && blurSfw) isBlurred = true; + else if (rClass === 'untagged' && blurUntagged) isBlurred = true; + let thumbUrl = `/t/${c.item_id}.webp`; + if (isBlurred && (rClass === 'nsfw' || rClass === 'nsfl')) { + thumbUrl = `/t/${c.item_id}_blur.webp`; + } + if (window.applyThumbCacheBust) thumbUrl = window.applyThumbCacheBust(thumbUrl); + mediaHtml = ``; itemPreview = `
- ${mediaHtml} + ${mediaHtml} ${(window.f0ckI18n && window.f0ckI18n.sidebar_view) || 'View'} »
`; } diff --git a/src/inc/locales/de.json b/src/inc/locales/de.json index 84da1bd..f311407 100644 --- a/src/inc/locales/de.json +++ b/src/inc/locales/de.json @@ -156,7 +156,7 @@ "blur_sfw": "SFW weichzeichnen", "blur_sfw_hint": "Zeichnet SFW-Vorschaubilder weich.", "blur_untagged": "Unmarkierte weichzeichnen", - "blur_untagged_hint": "Zeichnet unmarkierte Vorschaubilder weich. Klicken zum Aufdecken, Klick auf das durchgestrichene Auge zum erneuten Falten.", + "blur_untagged_hint": "Zeichnet unmarkierte Vorschaubilder weich.", "render_emojis": "Emojis in Zitatantworten anzeigen", "render_emojis_hint": ":emoji:-Bilder in >zitierten Zeilen anzeigen", "embed_yt": "YouTube-Videos in Kommentaren einbetten", diff --git a/src/inc/locales/zange.json b/src/inc/locales/zange.json index 086a453..e92fbe9 100644 --- a/src/inc/locales/zange.json +++ b/src/inc/locales/zange.json @@ -149,14 +149,14 @@ "image_expand_on_click_hint": "Anstatt dat Scroll-Zoom-Moped aufzumache, wird n Bild beim Klickle uff volle Größ im Bereich uffgepumpt.", "enable_bg_blur": "Hintergrundunschärfe aktivieren", "enable_bg_blur_hint": "Gefalteten Hintergrund auf Elementen anzeigen", - "blur_nsfw": "NSFW falten", - "blur_nsfw_hint": "Faltet NSFW-Vorschaubilder.", - "blur_nsfl": "NSFL falten", - "blur_nsfl_hint": "Faltet NSFL-Vorschaubilder.", - "blur_sfw": "SFW falten", - "blur_sfw_hint": "Faltet SFW-Vorschaubilder.", - "blur_untagged": "Unmarkierte falten", - "blur_untagged_hint": "Faltet unmarkierte Vorschaubilder.", + "blur_nsfw": "NSFW verwischen", + "blur_nsfw_hint": "Verwischt NSFW-Vorschaubilder.", + "blur_nsfl": "NSFL verwischen", + "blur_nsfl_hint": "Verwischt NSFL-Vorschaubilder.", + "blur_sfw": "SFW verwischen", + "blur_sfw_hint": "Verwischt SFW-Vorschaubilder.", + "blur_untagged": "Unmarkierte verwischen", + "blur_untagged_hint": "Verwischt unmarkierte Vorschaubilder.", "render_emojis": "Emojis in Zitatantworten darstellen", "render_emojis_hint": ":emoji:-Bilder innerhalb von >zitierten Zeilen anzeigen", "embed_yt": "Röhrenelfen in Kommentaren einbetten", diff --git a/src/inc/routes/comments.mjs b/src/inc/routes/comments.mjs index feccaec..8a2b4da 100644 --- a/src/inc/routes/comments.mjs +++ b/src/inc/routes/comments.mjs @@ -418,8 +418,23 @@ export default (router, tpl) => { } // Notify for live updates - // Fetch the trigger-updated xd_score from the DB (trigger runs synchronously before we get here) - const [xdRow] = await db`SELECT xd_score FROM items WHERE id = ${item_id}`; + // Fetch the trigger-updated xd_score and the item rating tag from the DB (trigger runs synchronously before we get here) + const itemQuery = await db` + SELECT + i.xd_score, + (SELECT ta.tag_id FROM tags_assign ta + WHERE ta.item_id = i.id AND ta.tag_id = ANY(${[1, 2, cfg.nsfl_tag_id || 3]}::int[]) + ORDER BY ta.tag_id LIMIT 1) AS rating_tag_id + FROM items i WHERE i.id = ${item_id} + `; + const xdRow = itemQuery[0]; + const ratingTagId = itemQuery[0]?.rating_tag_id; + let ratingLabel = '?'; + let ratingClass = 'untagged'; + if (ratingTagId == 1) { ratingLabel = 'SFW'; ratingClass = 'sfw'; } + else if (ratingTagId == 2) { ratingLabel = 'NSFW'; ratingClass = 'nsfw'; } + else if (ratingTagId == (cfg.nsfl_tag_id || 3)) { ratingLabel = 'NSFL'; ratingClass = 'nsfl'; } + // Truncate body to 500 chars: PostgreSQL NOTIFY has an 8000-byte hard limit. // Large comments would silently drop the notification. The client fetches // the full content via _silentSync; the NOTIFY only needs to trigger the update. @@ -450,7 +465,14 @@ export default (router, tpl) => { item_id: item_id, type: 'comment', body: notifyBody, - id: commentId + id: commentId, + item_rating_class: ratingClass, + item_rating_label: ratingLabel, + avatar: req.session.avatar, + avatar_file: req.session.avatar_file, + username: req.session.user, + username_color: req.session.username_color, + display_name: req.session.display_name || null })); // Automatically subscribe user to the thread @@ -806,6 +828,9 @@ export default (router, tpl) => { i.mime, i.id as item_id, i.dest as item_dest, + (SELECT ta.tag_id FROM tags_assign ta + WHERE ta.item_id = i.id AND ta.tag_id = ANY(${[1, 2, cfg.nsfl_tag_id || 3]}::int[]) + ORDER BY ta.tag_id LIMIT 1) AS rating_tag_id, u.user as username, uo.avatar, uo.avatar_file, @@ -827,10 +852,18 @@ export default (router, tpl) => { `; const processedComments = comments.map(c => { + let ratingLabel = '?'; + let ratingClass = 'untagged'; + if (c.rating_tag_id == 1) { ratingLabel = 'SFW'; ratingClass = 'sfw'; } + else if (c.rating_tag_id == 2) { ratingLabel = 'NSFW'; ratingClass = 'nsfw'; } + else if (c.rating_tag_id == (cfg.nsfl_tag_id || 3)) { ratingLabel = 'NSFL'; ratingClass = 'nsfl'; } + return { ...c, content: (c.content || '').trim(), - username_color: c.username_color + username_color: c.username_color, + item_rating_class: ratingClass, + item_rating_label: ratingLabel // created_at stays as the raw ISO timestamp so the frontend f0ckTimeAgo can localize it }; });